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 相关文章推荐
Python3基础之输入和输出实例分析
Aug 18 Python
使用pdb模块调试Python程序实例
Jun 02 Python
python2 与 pyhton3的输入语句写法小结
Sep 10 Python
django框架基于模板 生成 excel(xls) 文件操作示例
Jun 19 Python
python多线程同步实例教程
Aug 11 Python
python hashlib加密实现代码
Oct 17 Python
使用Python实现分别输出每个数组
Dec 06 Python
Python模拟FTP文件服务器的操作方法
Feb 18 Python
python numpy实现多次循环读取文件 等间隔过滤数据示例
Mar 14 Python
python批量修改交换机密码的示例
Sep 22 Python
Python爬虫实战之爬取携程评论
Jun 02 Python
解决pycharm安装scrapy DLL load failed:找不到指定的程序的问题
Jun 08 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
WAR3重制版DOTA 5V5初体验
2020/04/09 DOTA
我的论坛源代码(二)
2006/10/09 PHP
php中preg_match的isU代表什么意思
2015/10/01 PHP
php版微信公众平台入门教程之开发者认证的方法
2016/09/26 PHP
PHP+MySQL实现消息队列的方法分析
2018/05/09 PHP
php常用字符串查找函数strstr()与strpos()实例分析
2019/06/21 PHP
PHP中abstract(抽象)、final(最终)和static(静态)原理与用法详解
2020/06/05 PHP
基于PHP实现堆排序原理及实例详解
2020/06/19 PHP
EasySlider 基于jQuery功能强大简单易用的滑动门插件
2010/06/11 Javascript
JavaScript 对象深入学习总结(经典)
2015/09/29 Javascript
简易的JS计算器实现代码
2016/10/18 Javascript
Javascript的动态增加类的实现方法
2016/10/20 Javascript
基于Bootstrap分页的实例讲解(必看篇)
2017/07/04 Javascript
JQuery实现table中tr上移下移的示例(超简单)
2018/01/08 jQuery
解决vue-cli项目打包出现空白页和路径错误的问题
2018/09/04 Javascript
JavaScript实现随机点名器实例详解
2019/05/07 Javascript
微信小程序 弹窗输入组件的实现解析
2019/08/12 Javascript
js+canvas实现图片格式webp/png/jpeg在线转换
2020/08/22 Javascript
vant 中van-list的用法说明
2020/11/11 Javascript
python 判断是否为正小数和正整数的实例
2017/07/23 Python
Python配置mysql的教程(推荐)
2017/10/13 Python
python获取命令行输入参数列表的实例代码
2018/06/23 Python
Python动态生成多维数组的方法示例
2018/08/09 Python
在pytorch中查看可训练参数的例子
2019/08/18 Python
django中使用POST方法获取POST数据
2019/08/20 Python
解析Python3中的Import
2019/10/13 Python
基于HTML5 Canvas的3D动态Chart图表的示例
2017/11/02 HTML / CSS
Audible英国:有声读物,30天免费试用
2019/10/16 全球购物
意大利比基尼品牌:MISS BIKINI
2019/11/02 全球购物
干部现实表现材料
2014/02/13 职场文书
部门经理迟到检讨书
2015/02/16 职场文书
对外汉语教师推荐信
2015/03/27 职场文书
夫妻吵架保证书
2015/05/08 职场文书
Element实现动态表格的示例代码
2021/08/02 Javascript
关于Python中*args和**kwargs的深入理解
2021/08/07 Python
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
2022/06/14 MySQL