Python多线程结合队列下载百度音乐的方法
本文实例讲述了Python多线程结合队列下载百度音乐的方法。分享给大家供大家参考。具体如下:
一直想做个下载音乐的脚本,后来决定就拿百度音乐开刀,经过多次分析,终于制作了一个下载百度音乐的脚本,目前只默认下载第一页,童鞋们可以自由拓展。
适用Windows和Linux平台、依赖BeautifulSoup这个库,主要对HTML进行解析
#!/usr/bin/python #-*-coding:utf-8-*- ''' 百度中批量下载某歌手的歌(目前只下载第一页,可以自行拓展) @author:admin @qq:1243385033 ''' importthreading,urllib2,os,re,sys frombs4importBeautifulSoup fromQueueimportQueue '''目标歌手''' 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=" classDownloader(threading.Thread): def__init__(self,task): threading.Thread.__init__(self) self.task=task defrun(self): '''覆盖父类的run方法''' whileTrue: url=self.task.get() self.download(url) self.task.task_done() defbuild_path(self,filename): join=os.path.join parentPath=join(SAVE_FOLDER,SINGER) filename=filename+'.mp3' myPath=join(parentPath,filename) returnmyPath defdownload(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) withopen(save_path,"wb")ashandler: whileTrue: chunk=handle.read(1024) ifnotchunk: break handler.write(chunk) msg=u"已经从%s下载完成"%req_url sys.stdout.write(msg) sys.stdout.flush() classHttpRequest: 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)) defencode2utf8(self,source): ifsourceandisinstance(source,(str,unicode)): source=source.encode("utf8") returnsource returnsource defmkDir(self,dir_name): ifnotos.path.exists(dir_name): os.mkdir(dir_name) definit(self): self.mkDir(SAVE_FOLDER) subPath=os.path.join(SAVE_FOLDER,SINGER) self.mkDir(subPath) defhttp_request(self): globalsong_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 fora_taginspan_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) ifnoturl1ornoturl2: continue url=url1[0][:url1[0].rindex('/')+1]+url2[0] self.task.append({song_name:url}) returnself.task defstart_download(urls): #创建一个队列 quene=Queue() #获取list的大小 size=len(urls) #开启线程 for_inxrange(size): t=Downloader(quene) t.setDaemon(True) t.start() #入队列 forurlinurls: quene.put(url) quene.join() if__name__=='__main__': http=HttpRequest() urls=http.http_request() start_download(urls)
希望本文所述对大家的Python程序设计有所帮助。