1. 程式人生 > >一步步分析百度音樂的播放地址,利用Python爬蟲批量下載

一步步分析百度音樂的播放地址,利用Python爬蟲批量下載

百度音樂不需要登入也可以下載?聽到這個訊息是不是很興奮呢,

接下來我們開啟百度音樂,隨便開啟一首歌,切換到百度播放頁面:如圖

我這裡用的是Firfox 瀏覽器,開啟firebug 先清空所有的請求,如圖:


現在我們重新重新整理下頁面,看到這個.mp3的地址就是百度音樂的地址,我們可以直接複製到迅雷裡下載,但是這種做法太初級了吧,如果有很多首歌曲呢,每個都這樣複製,豈不是很麻煩啊。,接下來我們繼續分析。

這個連結有個特點,就是music/1658513  這個是什麼呢? 你猜的沒錯,這個是每首歌曲的Id ,再看後面的引數xcode 這個是個guid ,經過對比之後,每個都不一樣,這個從哪來的啊。。我們繼續分析其他請求。。

哈哈,還是被我們找到了吧,這個songLink 就是音樂的地址,但是這個請求是怎麼來的呢,我們繼續往上找,我們看到post請求裡的引數,有個songIds 這個就是每首歌的Id,

到了這一步,一切都很順利,把這個地址複製下來,接下來,該我們的Python出場了。。

 這裡使用的環境是Python3.4  ,第三方庫BeautifulSoup,requests,怎麼安裝,網上有很多,接下來上程式碼

新建一個xml檔案取名為music.xml 格式如下

<?xml version="1.0" encoding="utf-8"?>
<root>
    <url
>http://music.baidu.com/tag/純淨</url> <pageSize>40</pageSize> <savePlay>d:\\純淨\\</savePlay> </root>
url 是百度音樂的分類地址 pageSize 是要下載的頁數,savePlay 是儲存的路徑

接下來我們再建一個py檔案 主要程式碼部分:

模擬瀏覽器請求,防止被遮蔽

headers={
            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0'
, 'Referer':'http://play.xml.baidu.com/', 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Encoding':'gzip, deflate, br', 'Accept-Language':'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3', 'Cache-Control':'max-age=0', 'Connection':'keep-alive' } 讀取xml檔案的方法
def getTagText(tag):
    rc = ""
dom=xml.dom.minidom.parse("play.xml")
    node = dom.getElementsByTagName(tag)[0]
    for node in node.childNodes:
        if node.nodeType in ( node.TEXT_NODE, node.CDATA_SECTION_NODE):
            rc=node.data
    return rc

解析html方法

def DownHtml(url):
        try:
           savePlay=getTagText("savePlay")
           print("準備開始解析頁面:"+url+"  請稍候...")
           html=requests.get(url,headers=headers,timeout=2000)
           html.encoding="utf-8"
soup=BeautifulSoup(html.text,"html.parser")
           div_html=soup.find("div",class_="search-song-list song-list song-list-hook")
           span_html=re.findall('<span class="music-icon-hook" data-musicicon=\'(.*?)\'>',str(div_html))
           for v in span_html:
               data=json.loads(v)
               play=data["id"],data["songTitle"]
               queue.append(play)
           while queue:
               time.sleep(5) 
               music_tuple=queue.popleft()
               playUrl=music.replace("$0$",music_tuple[0])
               print(music_tuple[1]+".mp3進入下載通道,開始排隊等待...\n")
               resultJson=requests.get(playUrl,headers=headers,timeout=2000)
               data=resultJson.json()
               if not data['data']:
                   pass
               else:
                   v=data["data"]["songList"][0];
                   print("正在下載, "+v["songName"]+".mp3 ...\n")
                   time.sleep(2)
                   request.urlretrieve(v["songLink"],savePlay+v["songName"]+".mp3")
                   print(v["songName"]+".mp3 下載完成,下載路徑:"+savePlay+v["songName"]+".mp3")
        except:
            pass
if __name__=="__main__":
    start = time.time()
    pageSize=int(getTagText("pageSize"))
    pageIndex=25
url=getTagText("url")
    playurls.append(url)
    if pageSize>1:
        for v in range(pageSize):
            if v>0:
                purl=url+"?start="+str(pageIndex)+"&size=25&third_type=0"
playurls.append(purl)
                pageIndex+=25
with Pool(4)as p:
        p.map(DownHtml,playurls)

    print("本次下載共用時:"+time.time()-start)
最後發個截圖,一起來看看我們執行的效果吧, ps :新手自學,如有不足的地方,歡迎指正,環境是在vs2013上開發的,如果其他ide可以單獨複製出py,和xml 檔案   原始碼地址