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实现父类调用两种方法的不同
Jan 15 Python
python中使用xlrd读excel使用xlwt写excel的实例代码
Jan 31 Python
Python中存取文件的4种不同操作
Jul 02 Python
通过python将大量文件按修改时间分类的方法
Oct 17 Python
Python中logging.NullHandler 的使用教程
Nov 29 Python
python实现趣味图片字符化
Apr 30 Python
python安装numpy和pandas的方法步骤
May 27 Python
Python脚本利用adb进行手机控制的方法
Jul 08 Python
30行Python代码实现高分辨率图像导航的方法
May 22 Python
Python pip使用超时问题解决方案
Aug 03 Python
Python Selenium实现无可视化界面过程解析
Aug 25 Python
matplotlib之pyplot模块实现添加子图subplot的使用
Apr 25 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
音乐朗读剧《MARS RED》2021年TV动画化决定!
2020/03/06 日漫
使用php检测用户当前使用的浏览器是否为IE浏览器
2013/12/03 PHP
ThinkPHP分页类使用详解
2014/03/05 PHP
基于php实现的php代码加密解密类完整实例
2016/10/12 PHP
Yii 2中的load()和save()示例详解
2017/08/03 PHP
Laravel中Facade的加载过程与原理详解
2017/09/22 PHP
PHP使用星号替代用户名手机和邮箱的实现代码
2018/02/07 PHP
ThinkPHP5框架中使用JWT的方法示例
2020/06/03 PHP
JS getMonth()日期函数的值域是0-11
2010/02/15 Javascript
jquery 插件学习(四)
2012/08/06 Javascript
jquery批量设置属性readonly和disabled的方法
2014/01/24 Javascript
中文输入法不触发onkeyup事件的解决办法
2014/07/09 Javascript
JavaScript SHA512&amp;SHA256加密算法详解
2015/08/11 Javascript
JS鼠标拖拽实例分析
2015/11/23 Javascript
分享一些常用的jQuery动画事件和动画函数
2015/11/27 Javascript
Webpack性能优化 DLL 用法详解
2017/08/10 Javascript
React Native react-navigation 导航使用详解
2017/12/01 Javascript
脚手架vue-cli工程webpack的基本用法详解
2018/09/29 Javascript
ES6知识点整理之数组解构和字符串解构的应用示例
2019/04/17 Javascript
layui使用button按钮 点击出现弹层 弹层中加载表单的实例
2019/09/04 Javascript
Vue 实现复制功能,不需要任何结构内容直接复制方式
2019/11/09 Javascript
浅析vue-router实现原理及两种模式
2020/02/11 Javascript
Python实现PS图像抽象画风效果的方法
2018/01/23 Python
Transpose 数组行列转置的限制方式
2020/02/11 Python
Python configparser模块配置文件过程解析
2020/03/03 Python
python 获取字典特定值对应的键的实现
2020/09/29 Python
django inspectdb 操作已有数据库数据的使用步骤
2021/02/07 Python
英国手机零售商:Metrofone
2019/03/18 全球购物
德国最大的网上足球商店:11teamsports
2019/09/11 全球购物
JAVA高级程序员面试题
2013/09/06 面试题
环境科学专业个人求职信
2013/09/26 职场文书
社区学习十八大感想
2014/01/22 职场文书
标准自荐信范文
2014/01/29 职场文书
总经理文秘岗位职责
2014/02/03 职场文书
查摆问题自我剖析材料
2014/08/18 职场文书
Python爬虫之爬取二手房信息
2021/04/27 Python