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 相关文章推荐
简单介绍利用TK在Python下进行GUI编程的教程
Apr 13 Python
python实现数值积分的Simpson方法实例分析
Jun 05 Python
以视频爬取实例讲解Python爬虫神器Beautiful Soup用法
Jan 20 Python
python开发简易版在线音乐播放器
Mar 03 Python
Python 多线程实例详解
Mar 25 Python
Python格式化日期时间操作示例
Jun 28 Python
Python爬取qq空间说说的实例代码
Aug 17 Python
使用Python爬虫库requests发送请求、传递URL参数、定制headers
Jan 25 Python
python进行参数传递的方法
May 12 Python
Python连接mysql方法及常用参数
Sep 01 Python
python进行二次方程式计算的实例讲解
Dec 06 Python
Python爬虫之爬取某文库文档数据
Apr 21 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运行速度的一些小技巧分享
2012/07/03 PHP
微博短链接算法php版本实现代码
2012/09/15 PHP
用PHP提取中英文词语以及数字的首字母的方法介绍
2013/04/23 PHP
php switch语句多个值匹配同一代码块的实现
2014/03/03 PHP
php中explode函数用法分析
2014/11/15 PHP
PHP实现上传多文件示例代码
2017/02/20 PHP
用js怎么把&amp;字符换成&quot;&amp;amp:&quot;
2006/10/19 Javascript
深入理解jQuery中live与bind方法的区别
2013/12/18 Javascript
Javascript实现网络监测的方法
2015/07/31 Javascript
直接拿来用的15个jQuery代码片段
2015/09/23 Javascript
javascript 中iframe高度自适应(同域)实例详解
2017/05/16 Javascript
JavaScript 中定义函数用 var foo = function () {} 和 function foo()区别介绍
2018/03/01 Javascript
vue.js配合$.post从后台获取数据简单demo分享
2018/08/11 Javascript
jQuery实现的简单歌词滚动功能示例
2019/01/07 jQuery
微信小程序HTTP接口请求封装代码实例
2019/09/05 Javascript
JavaScript代码异常监控实现过程详解
2020/02/17 Javascript
Vue列表循环从指定下标开始的多种解决方案
2020/04/08 Javascript
js实现飞机大战游戏
2020/08/26 Javascript
python中如何使用朴素贝叶斯算法
2017/04/06 Python
详解python 注释、变量、类型
2018/08/10 Python
Python 做曲线拟合和求积分的方法
2018/12/29 Python
django 实现编写控制登录和访问权限控制的中间件方法
2019/01/15 Python
python3 pathlib库Path类方法总结
2019/12/26 Python
Python colormap库的安装和使用详情
2020/10/06 Python
使用HTML5原生对话框元素并轻松创建模态框组件
2019/03/06 HTML / CSS
html5通过postMessage进行跨域通信的方法
2017/12/04 HTML / CSS
美国精油公司:Plant Therapy
2019/05/17 全球购物
Android面试题附答案
2014/12/08 面试题
用JAVA实现一种排序,JAVA类实现序列化的方法(二种)
2014/04/23 面试题
社区活动邀请函范文
2014/01/29 职场文书
房地产促销活动方案
2014/03/01 职场文书
中学生寄语大全
2014/04/03 职场文书
2015年学校德育工作总结
2015/04/22 职场文书
2015年维修工作总结
2015/04/25 职场文书
《桂花雨》教学反思
2016/02/19 职场文书
MySQL中int (10) 和 int (11) 的区别
2022/01/22 MySQL