1. 程式人生 > >python3 requets+re 批量爬取千千(原百度)音樂

python3 requets+re 批量爬取千千(原百度)音樂

 

以前實驗室同學需要文章和音樂,需要用爬蟲爬.....要做東西參加比賽,表示好久都沒寫爬蟲了....正如今天的正題,批量爬取千千音樂(原百度音樂)...博主會寫下爬取的過程和心得(採坑記錄),批量下載的音樂的有效程式碼雖然才50多行,但是採坑會花費大量時間和精力...

老規矩放幾張鎮樓圖正好博主也正在爬資料.....程式碼會自動建立在桌面的資料夾,裡面包含8種類別的子資料夾(資料夾的種類會隨著tag類別列表中個數增加而增加,可以更改,增加或者刪除),子資料夾中會儲存音樂。

 

首先進入千千音樂首頁,點選千千音樂,然後進入分類:會發現有很多種類的音樂,我們要批量爬取就需要解析每一類的音樂,當然這裡面有的類,都可以在tag列表裡面新增或者修改。

我們點選安靜類別的音樂,發現列出20首音樂在每一頁頁面上,都在網頁中li標籤中,每一首歌都有一個獨有的song_id

當我們點選頁面 那首歌,就會進入播放頁面,播放當前音樂,因為伺服器有請求音樂的連線,但是被隱藏起來在,所以不得不花費大量時間去找。

由於博主踩過了很多坑,這裡我就直接告訴大家音樂的連線怎麼找,每一首的音樂資源都會由唯一的song_id,在js裡面再次請求,拿到音樂資源的資訊,如下圖:

 

第一張圖上面網址進行請求後會得到,圖二的返回歌曲的資訊,包括歌曲的源出去,file_link=後面的地址,進行請求的時候,就能下載,會提示下載如下:

所以file_link就是每首歌的地址,當我們直接複製進行請求就能下載了,付費 的歌曲也可以!是不是很神奇,所以找歌曲的源資訊到大概講解到這裡就結束了。

接下來就是50多行程式碼實現的過程:

定義4個函式,分別如下,Get_text()實現網頁請求得到頁面的資訊,返回text型別的資料。get_songId解析每一頁20首歌曲的song_id,返回一個列表,傳給下載音樂的函式download_music使用,進行音樂下載。dowanload_music就是下載音樂的過程。

def Get_text(url):
def get_songId(html):
def download_music(song_ids,tag):
def main():

接下來,就說下兩個函式的要點:main函式裡面對每類tag列表中類別進行爬取,然後對多頁請求:我們進行多次翻頁後對安靜類音樂分析:

# http://music.taihe.com/tag/安靜 安靜第一頁
# http://music.taihe.com/tag/安靜?start=20&size=20&third_type=0 安靜第二頁
# http://music.taihe.com/tag/安靜?start=40&size=20&third_type=0 安靜第三頁

可以發現每一類是20首音樂,也就是size=20,第二頁:start=20,表示從20開始到請求20首後40結束,第三頁:start 40,表示從40開始,請求20首到60結束,所以我們可以發現規律,是第幾頁就是i*20開始,size為20的請求,i從0開始,由此可以推得第五頁是80開始,到100結束。我們下載100首就迴圈5次,需要很多就迴圈更多次。

def main():
    #音樂型別
    tags=['安靜','美好','輕鬆','舒服','喜悅','想念','唯美','小清晰']
    ##桌面路徑(依據每個人的電腦情況可以更改路徑)
    path = "D:\QQPCMgr(1)\Desktop\音樂\\"
    #建立每個音樂種類資料夾分類
    for tag in tags:
        #判斷每種類別音樂資料夾是否存在,不存在就建立
        if not os.path.exists(path+tag):
            os.mkdir(path+tag)
    tag_url="http://music.taihe.com/tag/"
    for tag in tags:
        #每頁20首,下載5頁
        for num in range(5):
            start_url=tag_url+tag+"?start=%s&size=20&third_type=0"%str(num*20)
            #獲取每頁的資訊
            html = Get_text(start_url)
            #h獲取每頁的每首歌的id
            song_ids=get_songId(html)
            #下載
            download_music(song_ids,tag)
if __name__ == '__main__':
    main()

接下來就下載音樂的函式:我們把每首歌的song_id拿到後,再去動態拼接資源網址:只需要把songid=後面新增拿到的id就行,再次進行請求得到音樂資源的資訊。這個網址可以在F12裡面進行找,不是固定的,每一首可能有點不一樣,但是都可以用,只需要songid就行。

http://musicapi.taihe.com/v1/restserver/ting?method=baidu.ting.song.playAAC&format=jsonp&callback=jQuery172009464779806914603_1542961432060&songid=%s&from=web&_=1542961435466"%song_id

把每個id拿去與上面的網址動態拼接,再請求就是每一首歌的資訊,由於返回的是json格式的資料,所以需要需要轉換成字典,

需要用json.loads把資料轉換成字典,在去取歌曲的資訊。需要的是歌名,歌手,歌曲連結,當然還有其他的也可以自己根據需要獲取。就貼出原始碼:有問題可以點選左上角頭像,微信向博主提問也可以留言反饋...

 

# coding=gbk
import requests,re,json,os

def Get_text(url):
    try:
        r=requests.get(url)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        print("請求成功")
        return r.text
    except:
        print("請求失敗")

def get_songId(html):
    #正則取出每一頁歌曲的songid
    songIds=re.findall(r'<a href="/song/(.*?)".*?',html)
    # print(songIds)
    return songIds
def download_music(song_ids,tag):
    for song_id in song_ids:
        #拼接每一首歌的songid
        url="http://musicapi.taihe.com/v1/restserver/ting?method=baidu.ting.song.playAAC&format=jsonp&callback=jQuery172009464779806914603_1542961432060&songid=%s&from=web&_=1542961435466"%song_id
        #再次請求
        html=Get_text(url)
        try:
            #z正則取出songid
            data=re.findall(r'\((.*?)\)',html)[0]
            #轉換成字典
            data=json.loads(data)
        except:
            continue
        print("歌曲地址:"+data['bitrate']['file_link'])
        try:
            print("歌曲:"+data['songinfo']['title'])
            print("歌手:"+data['songinfo']['author'])
        except:
            continue
        author=data['songinfo']['author']
        song_name=data['songinfo']['title']
        url=data['bitrate']['file_link']
        try:
            sorce=requests.get(url)
            print("音樂%s獲取成功"%song_name)
        except:
            print("*****音樂%s獲取失敗****"%song_name)
            continue
        #儲存在桌面的檔案路徑下
        path="D:\QQPCMgr(1)\Desktop\音樂\\"
        name=tag+'/'
        with open(path+name+author+'-'+song_name+'.mp3',"wb") as file:
            try:
                file.write(sorce.content)
                file.close()
                print("##%s下載成功##"%song_name)
            except:
                print("***********%s下載失敗*********"%song_name)

def main():
    #音樂型別
    tags=['安靜','美好','輕鬆','舒服','喜悅','想念','唯美','小清晰']
    ##桌面路徑(依據每個人的電腦情況可以更改路徑)
    path = "D:\QQPCMgr(1)\Desktop\音樂\\"
    #建立每個音樂種類資料夾分類
    for tag in tags:
        #判斷每種類別音樂資料夾是否存在,不存在就建立
        if not os.path.exists(path+tag):
            os.mkdir(path+tag)
    tag_url="http://music.taihe.com/tag/"
    for tag in tags:
        #每頁20首,下載5頁
        for num in range(5):
            start_url=tag_url+tag+"?start=%s&size=20&third_type=0"%str(num*20)
            #獲取每頁的資訊
            html = Get_text(start_url)
            #h獲取每頁的每首歌的id
            song_ids=get_songId(html)
            #下載
            download_music(song_ids,tag)
if __name__ == '__main__':
    main()