Python多線程結(jié)合隊(duì)列下載百度音樂的方法
本文實(shí)例講述了Python多線程結(jié)合隊(duì)列下載百度音樂的方法。分享給大家供大家參考。具體如下:
一直想做個下載音樂的腳本,后來決定就拿百度音樂開刀,經(jīng)過多次分析,終于制作了一個下載百度音樂的腳本,目前只默認(rèn)下載第一頁,童鞋們可以自由拓展。
適用Windows和Linux平臺、依賴BeautifulSoup這個庫,主要對HTML進(jìn)行解析
#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
百度中批量下載某歌手的歌(目前只下載第一頁,可以自行拓展)
@author:admin
@qq: 1243385033
'''
import threading, urllib2, os,re,sys
from bs4 import BeautifulSoup
from Queue import Queue
'''目標(biāo)歌手'''
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"已經(jīng)從 %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
'''發(fā)起請求'''
response=urllib2.urlopen(self.target_url)
# 獲取頭信息
content = response.read()
response.close()
# 使用BeautifulSoup
html = BeautifulSoup(content, from_encoding="utf8")
# 提取HTML標(biāo)簽
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):
#創(chuàng)建一個隊(duì)列
quene=Queue()
#獲取list的大小
size=len(urls)
#開啟線程
for _ in xrange(size):
t=Downloader(quene)
t.setDaemon(True)
t.start()
#入隊(duì)列
for url in urls:
quene.put(url)
quene.join()
if __name__=='__main__':
http=HttpRequest()
urls=http.http_request()
start_download(urls)
希望本文所述對大家的Python程序設(shè)計有所幫助。
相關(guān)文章
在Windows中設(shè)置Python環(huán)境變量的實(shí)例講解
下面小編就為大家分享一篇在Windows中設(shè)置Python環(huán)境變量的實(shí)例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04
國產(chǎn)麒麟系統(tǒng)kylin部署python項(xiàng)目詳細(xì)步驟
這篇文章主要給大家介紹了關(guān)于國產(chǎn)麒麟系統(tǒng)kylin部署python項(xiàng)目的相關(guān)資料,文中通過代碼示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09
Flask實(shí)現(xiàn)圖片的上傳、下載及展示示例代碼
這篇文章主要介紹了Flask實(shí)現(xiàn)圖片的上傳、下載及展示示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08
Python利用yield?form實(shí)現(xiàn)異步協(xié)程爬蟲
這篇文章主要為大家詳細(xì)介紹了Python如何利用yield?form實(shí)現(xiàn)異步協(xié)程爬蟲。其實(shí)這是很古老的用法了,現(xiàn)在大多用的aiohttp庫實(shí)現(xiàn),這篇記錄僅僅用做個人的協(xié)程底層實(shí)現(xiàn)的學(xué)習(xí),希望對大家有所幫助2022-11-11
tensorflow如何繼續(xù)訓(xùn)練之前保存的模型實(shí)例
今天小編就為大家分享一篇tensorflow如何繼續(xù)訓(xùn)練之前保存的模型實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01

