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语言的变量认识及操作方法
Feb 11 Python
TensorFlow神经网络优化策略学习
Mar 09 Python
python实现守护进程、守护线程、守护非守护并行
May 05 Python
Pycharm+Scrapy安装并且初始化项目的方法
Jan 15 Python
Django如何防止定时任务并发浅析
May 14 Python
pycharm 2019 最新激活方式(pycharm破解、激活)
Sep 22 Python
python range实例用法分享
Feb 06 Python
MxNet预训练模型到Pytorch模型的转换方式
May 25 Python
Python单元测试及unittest框架用法实例解析
Jul 09 Python
详解Python遍历列表时删除元素的正确做法
Jan 07 Python
用PYTHON去计算88键钢琴的琴键频率和音高
Apr 10 Python
如何基于python实现单目三维重建详解
Jun 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
深入理解:XML与对象的序列化与反序列化
2013/06/08 PHP
PHP PDOStatement:bindParam插入数据错误问题分析
2013/11/13 PHP
Yii2中cookie用法示例分析
2016/07/18 PHP
PHP 将dataurl转成图片image方法总结
2016/10/14 PHP
django中的ajax组件教程详解
2018/10/18 PHP
Jquery中删除元素的实现代码
2011/12/29 Javascript
一个基于jquery的文本框记数器
2012/09/19 Javascript
js replace正则表达式应用案例讲解
2013/01/17 Javascript
Javascript中Array.prototype.map()详解
2014/10/22 Javascript
JavaScript跨平台的开源框架NativeScript
2015/03/24 Javascript
js同源策略详解
2015/05/21 Javascript
Bootstrap Metronic完全响应式管理模板学习笔记
2016/07/08 Javascript
BootStrap点击保存后实现模态框自动关闭的思路(模态框)
2017/09/26 Javascript
使用nodeJs来安装less及编译less文件为css文件的方法
2017/11/20 NodeJs
vue实现菜单切换功能
2019/05/08 Javascript
JS扁平化输出数组的2种方法解析
2019/09/17 Javascript
JavaScript异步操作的几种常见处理方法实例总结
2020/05/11 Javascript
[07:27]DOTA2卡尔工作室 英雄介绍水晶室女篇
2013/06/21 DOTA
Python求解任意闭区间的所有素数
2018/06/10 Python
Python使用ctypes调用C/C++的方法
2019/01/29 Python
Python通过TensorFlow卷积神经网络实现猫狗识别
2019/03/14 Python
Python OS模块实例详解
2019/04/15 Python
linux中如何使用python3获取ip地址
2019/07/15 Python
Tensorflow 模型转换 .pb convert to .lite实例
2020/02/12 Python
英国马匹装备和马术用品购物网站:Equine Superstore
2019/03/03 全球购物
Brydge英国:适用于Apple iPad和Microsoft Surface Pro的蓝牙键盘
2019/05/16 全球购物
Vrbo西班牙:预订您的度假公寓(公寓、乡村房屋…)
2020/04/27 全球购物
公司营业员的工作总结自我评价
2013/10/05 职场文书
医学毕业生自我鉴定
2013/10/30 职场文书
师范应届毕业生自荐信
2013/11/18 职场文书
30年同学聚会感言
2014/01/30 职场文书
公司总经理工作职责管理办法
2014/02/28 职场文书
纪念九一八事变83周年国旗下讲话稿
2014/09/15 职场文书
大学生创业,为什么都会选择快餐饮?
2019/08/08 职场文书
MySQL 1130异常,无法远程登录解决方案详解
2021/08/23 MySQL
python使用opencv对图像添加噪声(高斯/椒盐/泊松/斑点)
2022/04/06 Python