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()