Python多线程结合队列下载百度音乐的方法


Posted in Python onJuly 27, 2015

本文实例讲述了Python多线程结合队列下载百度音乐的方法。分享给大家供大家参考。具体如下:

一直想做个下载音乐的脚本,后来决定就拿百度音乐开刀,经过多次分析,终于制作了一个下载百度音乐的脚本,目前只默认下载第一页,童鞋们可以自由拓展。
适用Windows和Linux平台、依赖BeautifulSoup这个库,主要对HTML进行解析

#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
 百度中批量下载某歌手的歌(目前只下载第一页,可以自行拓展)
 @author:admin
 @qq: 1243385033
'''
import threading, urllib2, os,re,sys
from bs4 import BeautifulSoup
from Queue import Queue
'''目标歌手'''
SINGER = u'亚东'
'''保存路径'''
SAVE_FOLDER = 'F:/music/'
# 查询url
search_url = "http://music.baidu.com/search/song?key=%s&s=1"
# 百度音乐播放盒url
song_url = "http://box.zhangmen.baidu.com/x?op=12&count=1&mtype=1&title="
class Downloader(threading.Thread):
  def __init__(self, task):
    threading.Thread.__init__(self)
    self.task = task
  def run(self):
    '''覆盖父类的run方法'''
    while True:
      url = self.task.get()
      self.download(url)
      self.task.task_done()
  def build_path(self, filename):
    join = os.path.join
    parentPath=join(SAVE_FOLDER,SINGER)
    filename = filename + '.mp3'
    myPath = join(parentPath, filename)
    return myPath
  def download(self, url):
    '''下载文件'''
    sub_url = url.items()
    f_name = sub_url[0][0]
    req_url = sub_url[0][1]
    handle = urllib2.urlopen(req_url)
    # 保存路径
    save_path = self.build_path(f_name)
    with open(save_path, "wb") as handler:
      while True:
        chunk = handle.read(1024)
        if not chunk:
          break
        handler.write(chunk)
        msg = u"已经从 %s下载完成" % req_url
      sys.stdout.write(msg)
      sys.stdout.flush()
class HttpRequest:
  def __init__(self):
    self.task = []
    self.reg_decode = re.compile('<decode>.*?CDATA\[(.*?)\]].*?</decode>')
    self.reg_encode = re.compile('<encode>.*?CDATA\[(.*?)\]].*?</encode>')
    self.init()
    self.target_url = search_url % urllib2.quote(self.encode2utf8(SINGER))
  def encode2utf8(self,source):
    if source and isinstance(source,(str,unicode)):
      source=source.encode("utf8")
      return source
    return source
  def mkDir(self, dir_name):
    if not os.path.exists(dir_name):
      os.mkdir(dir_name)
  def init(self):
    self.mkDir(SAVE_FOLDER)
    subPath = os.path.join(SAVE_FOLDER, SINGER)
    self.mkDir(subPath)
  def http_request(self):
    global song_url
    '''发起请求'''
    response=urllib2.urlopen(self.target_url)
    # 获取头信息
    content = response.read()
    response.close()
    # 使用BeautifulSoup
    html = BeautifulSoup(content, from_encoding="utf8")
    # 提取HTML标签
    span_tag = html.find_all('div', {"monkey":"song-list"})[0].find_all('span', class_='song-title')
      # 遍历List
    for a_tag in span_tag:
      song_name = unicode(a_tag.find_all("a")[0].get_text())
      song_url = song_url + urllib2.quote(self.encode2utf8(song_name))
      song_url = song_url + '$$' + urllib2.quote(self.encode2utf8(SINGER)) + '$$$$&url=&listenreelect=0&.r=0.1696378872729838'
      xmlfile = urllib2.urlopen(song_url)
      xml_content = xmlfile.read()
      xmlfile.close()
      url1 = re.findall(self.reg_encode, xml_content)
      url2 = re.findall(self.reg_decode, xml_content)
      if not url1 or not url2:
        continue
      url = url1[0][:url1[0].rindex('/') + 1] + url2[0]
      self.task.append({song_name:url})
    return self.task
def start_download(urls):
  #创建一个队列
  quene=Queue()
  #获取list的大小
  size=len(urls)
  #开启线程
  for _ in xrange(size):
    t=Downloader(quene)
    t.setDaemon(True)
    t.start()
  #入队列
  for url in urls:
    quene.put(url)
  quene.join()
if __name__=='__main__':
  http=HttpRequest()
  urls=http.http_request()
  start_download(urls)

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
Python多线程编程(八):使用Event实现线程间通信
Apr 05 Python
处理Python中的URLError异常的方法
Apr 30 Python
详解Python中的条件判断语句
May 14 Python
Python实现Kmeans聚类算法
Jun 10 Python
numpy实现合并多维矩阵、list的扩展方法
May 08 Python
几行Python代码爬取3000+上市公司的信息
Jan 24 Python
Python学习笔记之字符串和字符串方法实例详解
Aug 22 Python
Python自动生成代码 使用tkinter图形化操作并生成代码框架
Sep 18 Python
Python OrderedDict的使用案例解析
Oct 25 Python
Python中Flask-RESTful编写API接口(小白入门)
Dec 11 Python
python实现多进程按序号批量修改文件名的方法示例
Dec 30 Python
浅谈Python描述数据结构之KMP篇
Sep 06 Python
在Django框架中设置语言偏好的教程
Jul 27 #Python
在Python的Django框架中创建语言文件
Jul 27 #Python
在Django的模型和公用函数中使用惰性翻译对象
Jul 27 #Python
使用Django的模版来配合字符串翻译工作
Jul 27 #Python
Django中的“惰性翻译”方法的相关使用
Jul 27 #Python
在Python中的Django框架中进行字符串翻译
Jul 27 #Python
Python中特殊函数集锦
Jul 27 #Python
You might like
PHP数组的交集array_intersect(),array_intersect_assoc(),array_inter_key()函数的小问题
2011/05/29 PHP
PHP中文分词 自动获取关键词介绍
2012/11/13 PHP
PHP模拟登陆163邮箱发邮件及获取通讯录列表的方法
2015/03/07 PHP
PHP序列化/对象注入漏洞分析
2016/04/18 PHP
thinkphp3.x自定义Action、Model及View的简单实现方法
2016/05/19 PHP
PHP迭代器和生成器用法实例分析
2019/09/28 PHP
关于jquery css的使用介绍
2013/04/18 Javascript
JQuery记住用户名和密码的具体实现
2014/04/04 Javascript
JavaScript验证图片类型(扩展名)的函数分享
2014/05/05 Javascript
javascript屏蔽右键代码
2014/05/15 Javascript
jQuery聚合函数实例
2015/05/21 Javascript
JS实现探测网站链接的方法【测试可用】
2016/11/08 Javascript
详解jQuery中ajax.load()方法
2017/01/25 Javascript
js实现会跳动的日历效果(完整实例)
2017/10/18 Javascript
jQuery 实现左右两侧菜单添加、移除功能
2018/01/02 jQuery
在vue和element-ui的table中实现分页复选功能
2019/12/04 Javascript
JS面向对象编程——ES6 中class的继承用法详解
2020/03/03 Javascript
javascript实现贪吃蛇小练习
2020/07/05 Javascript
vue setInterval 定时器失效的解决方式
2020/07/30 Javascript
JavaScript实现手风琴效果
2021/02/18 Javascript
python正则分组的应用
2013/11/10 Python
python 动态获取当前运行的类名和函数名的方法
2014/04/15 Python
基于python实现微信模板消息
2015/12/21 Python
OpenCV2.3.1+Python2.7.3+Numpy等的配置解析
2018/01/05 Python
Python爬虫实现百度图片自动下载
2018/02/04 Python
浅谈numpy生成数组的零值问题
2018/11/12 Python
Python使用crontab模块设置和清除定时任务操作详解
2019/04/09 Python
Pytorch之保存读取模型实例
2019/12/30 Python
Python3 io文本及原始流I/O工具用法详解
2020/03/23 Python
CSS3弹性伸缩布局之box布局
2016/07/12 HTML / CSS
html5 button autofocus 属性介绍及应用
2013/01/04 HTML / CSS
波兰最早的运动鞋精品店之一:Street Supply
2019/08/29 全球购物
Java中各种基本数据类型的默认值都是什么
2016/12/22 面试题
在职研究生自我鉴定
2013/10/16 职场文书
七年级音乐教学反思
2014/01/26 职场文书
公司员工辞职信范文
2015/05/12 职场文书