爬取網易雲音樂
本章說的是在網易雲中搜索某音樂或者歌手,從而下載搜索的內容的文章
外鏈地址: http://music.163.com/song/media/outer/url?id={}.mp3,外鏈是需要記住的,找是很難找到的
例如:http://music.163.com/song/media/outer/url?id=108418.mp3背對背擁抱
可以看出來只需要獲取每首歌曲的id即可獲取音樂的下載地址
-
分析網易雲音樂
首先搜索你想要的歌曲或者歌星,這裏以搜索林俊杰爲例
點擊進入到單曲
右擊檢查,進入到Network,因爲一般都是ajax請求,所以再點擊XHR然後刷新頁面
然後就需要開始分析下面的請求,可以發現在這個請求中返回的JSON數據正好與頁面中的數據相互匹配。
然後點開一個內容具體查看內容,發現裏面有很多id,那具體哪個是歌曲的id呢,其實是很好判斷的,每個id前面或者後面都跟着了name,name裏面的值就代表這個id是什麼的id,我們需要獲取歌曲所以選擇name爲不潮不花錢,id爲108463的的JSON數據,然後與文章開頭的外鏈url拼接之後發現正是歌曲的下載地址url = http://music.163.com/song/media/outer/url?id=108463.mp3
那就先獲取該JSON數據的請求url,發現是一個該請求是一個post請求,既然是post請求那麼一定有請求時的From Data,往下翻就會找到請求的參數,遺憾的是這個請求參數是加密了的,那麼如果想破解別的歌曲或者歌手的單曲,那麼久需要找到相應的From Data,然後在發送請求時更改一下From Fata數據即可
-
上代碼
寫好整體的結構並導入相關的庫,定義外鏈地址,請求頭,剛剛分析的From Data數據
import requests,os
class QQyinyue(object):
def __init__(self):
self.song_url = 'http://music.163.com/song/media/outer/url?id={}.mp3' # 這是網易雲音樂的播放音樂的外鏈地址,可以發現整個地址只是id不同,更改id即可獲取不同的音樂
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36'}
self.data = {'params': 'f/aZ47YnN/ARSX3MAN+RuDUjUpCKw/XhmYBfhAdUrnjZ5KkI2IXx3TfrBFLdGHqAxfVnif7xSysRF74vURIyzMSrroBf+4cPh9WMqQufLApOgH/5OLh/LZWgiZVeDMn8gQuBLu5szRXLrfNDXoPVlqeCC1hb4qrb5C30p5NLzbL3BSYzPIBd8urnSZMnTR3nnTrFZ7oxGfVzLPRF53QYjeitOlJJLlVTu8joB5hnU4lnQlGK2F2VU27YzrL51dy9yAEUjO5cjFY2Ocoa9vf6+A==',
'encSecKey': '1c0be5f6e973579de32be840d84c99bf021d63fa67db0e86f01bd589fe1e11d6ec9b66b9b4fc490711a8aad8160b36bbd39d7b52fff5bb4829270d9018c1ae24dc4258175a07fab990f7e1057ad5f1c4e601926628ad88117f455ff5371475a53df6f23c1a23b98ddd3cece5f1d14360d71c19f63d98fe8ffbae1f01cdd1c720'}
def parse_url(self):
pass
def save_songs(self):
pass
def main(self):
self.parse_url()
if __name__ == '__main__':
spider = QQyinyue()
spider.main()
- 注意點:
- 是post請求
- 換一個搜索內容然後分析響應內容,發現發送請求的url沒有變化,變得只是From Data,更改From Data就可以獲取自己下載的歌曲了,因爲只要是通過搜索歌曲或者歌星得到的這些數據,結構都是一樣的,所以提取id的方法也都是一樣的
因爲最外殼是一個字典形式,所以可以通過鍵取出所對應的值,然後發現歌曲的信息都在一個列表當中,所以需要去遍歷整個列表
分別提取歌名,id,歌星
當得到這個結果的時候說明離成功只要一步之遙
這時我們得到了id,歌名,歌星,剩下的就是將id和外鏈合併成爲歌曲的下載地址,然後保存時將歌名,歌星作爲保存後的歌名就大功告成了
注意:- 在開頭已經用{}初始化了外鏈下載地址
- 保存二進制文件要加.content,且打開文件的方式爲 什麼什麼b,如 ab,wb,rb
加一個print(‘正在下載{} {}’.format(song_name,actor))讓自己知道下載到哪裏了,不然下載完了都不知道
完整代碼
import requests,os
class QQyinyue(object):
def __init__(self):
self.song_url = 'http://music.163.com/song/media/outer/url?id={}.mp3' # 這是網易雲音樂的播放音樂的外鏈地址,可以發現整個地址只是id不同,更改id即可獲取不同的音樂
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36'} # headers可以不用加,但加了總沒錯
self.data = {'params': 'f/aZ47YnN/ARSX3MAN+RuDUjUpCKw/XhmYBfhAdUrnjZ5KkI2IXx3TfrBFLdGHqAxfVnif7xSysRF74vURIyzMSrroBf+4cPh9WMqQufLApOgH/5OLh/LZWgiZVeDMn8gQuBLu5szRXLrfNDXoPVlqeCC1hb4qrb5C30p5NLzbL3BSYzPIBd8urnSZMnTR3nnTrFZ7oxGfVzLPRF53QYjeitOlJJLlVTu8joB5hnU4lnQlGK2F2VU27YzrL51dy9yAEUjO5cjFY2Ocoa9vf6+A==',
'encSecKey': '1c0be5f6e973579de32be840d84c99bf021d63fa67db0e86f01bd589fe1e11d6ec9b66b9b4fc490711a8aad8160b36bbd39d7b52fff5bb4829270d9018c1ae24dc4258175a07fab990f7e1057ad5f1c4e601926628ad88117f455ff5371475a53df6f23c1a23b98ddd3cece5f1d14360d71c19f63d98fe8ffbae1f01cdd1c720'}
def parse_url(self):
response = requests.post('https://music.163.com/weapi/cloudsearch/get/web?csrf_token=', data=self.data, headers=self.headers).json() # .json()是將請求得到的json數據轉爲python中的字典數據
songs = response['result']['songs'] # 因爲最外殼是一個字典形式,所以可以通過鍵取出所對應的值
for song in songs:
song_name = song['name']
id = song['id']
ar = song['ar'] # 發現歌手的名字在一個列表當中,所以也需求去遍歷這個列表
for song_actor in ar:
actor = song_actor['name']
# print(id,song_name,actor)
self.save_songs(song_name,id,actor) # 注意這個的縮進在for循環的內部,如果在外部就是將for循環遍歷的最後一個結果傳給save_songs方法,在類class裏面叫方法,外面叫函數
def save_songs(self,song_name,id,actor):
filename = 'F:/音樂' # 保存的路徑
if not os.path.exists(filename): # 做個判斷,是否存在此路徑,若不存在則創建,注意這個創建的是文件夾,文件夾,文件夾,說三遍
os.makedirs(filename)
down_url = self.song_url.format(id) # 拼接完整的下載地址url
res = requests.get(down_url,headers = self.headers).content # .content是將其轉爲二進制數據
with open(filename+'/{} {}'.format(song_name,actor),'wb')as f: # 以wb方式打開文件,b就是binary的縮寫,代表二進制
f.write(res)
print('正在下載{} {}'.format(song_name,actor)) # 讓自己知道下載到哪裏了
def main(self):
self.parse_url()
if __name__ == '__main__':
spider = QQyinyue()
spider.main()
整體不足有很多,最不理想的就是不能直接讓用戶輸入歌名或者歌星直接下載歌曲,而是需要改變From Data信息獲取相對應的歌曲信息,這是爬取網易雲音樂的文章,下一次我會發爬取酷我音樂的文章,而且還是用戶輸入的哦,我第一次寫文章,希望與大家共同進步,一起加油