記一次簡易音樂爬蟲的編寫
我不裝了,我攤牌了,其實我的真實身份是一名愛看美女的學習up主(狗頭保命)
?
因為現(xiàn)在眾多音樂平臺下載歌曲都要收費了,導致我沒有車載音樂聽了。于是便自學爬蟲做了這個簡易的音樂爬蟲。不是那些大平臺的音樂爬蟲,是一個不知名的小音樂網站的爬蟲。下面開始正題:
首先,便是找不是那幾家大互聯(lián)網公司的音樂網站,在我的不懈努力之下終于找到了一家歌曲比較齊全的野雞音樂網站(請允許我這么說)。雖說是野雞,但是該有的熱門歌手的新歌和熱門歌曲都有,麻雀雖小,五臟俱全。
接著,便要對網站進行抓包,并對網頁鏈接尋找規(guī)律,當然,這個小網站的網頁鏈接的規(guī)律也是非常之簡單。如下圖所示:
?


不難發(fā)現(xiàn),它的網頁網址的規(guī)律,前面那一串不知名網址,加上你要搜索的的歌手的名字,然后再加上.html就可以了。于是乎,就解決了代碼中url的問題。代碼如下:
name = input()
url =?'http://www.2t58.com/so/{}/1.html'.format(name)
response = requests.get(url = url)
上面代碼目前是完全可行,雖然我并沒有加入heards等相關的反爬參數,但是網站在這目前為止也沒有進行反爬。
接下來,我們隨便點擊幾首歌曲:


因為喜歡周杰倫的朋友特別的多啊,我就搜索了周杰倫,并點了他的幾首歌曲,我們可以發(fā)現(xiàn),網頁欄的網頁地址變得毫無規(guī)律了,是一串我們看不懂的英文字母加上.html。而我們想要下載歌曲又必須進入到這個給頁面,所以我們必須找到它網頁地址的規(guī)律,或者說我們必須找到,那一串毫無規(guī)律的英文字母可以從哪個數據包中得到。接下來,我便進行了數據抓包并分析。?

很容易發(fā)現(xiàn),在每個a標簽的href中的最后一個字段就是我們要的那一串毫無規(guī)律的英文字母,所以我們要做的就是查看它的url,然后通過requests的模塊發(fā)送請求將這個網頁給請求下來,經過我的嘗試,該網站在這里進行了反爬,如果不加入heards則會請求不到數據,大家注意一下。然后,就是用正則表達式將我們需要的英文字母給匹配保留下來,代碼如下:
ex =?'<div class="name"><a href="/song/(.*?).html" target="_mp3">.*?</a></div>'
musicIndex = re.findall(ex,?response.text,?re.S)
接下來,就是回去歌曲的下載鏈接,將它以二進制形式保存就可以了。隨便點擊一首歌曲,對歌曲詳細頁面進行抓包。

數據包是非常多的,我們可以根據數據包的類型來有選擇型的查看,音頻和視頻等很顯然就是media類型的數據包。很顯然這就是我們想要的音樂鏈接,我們將它在一個單獨的網頁欄中搜索可以得到沒有限制可以直接下載的完整的音樂。但是我們要的是批量下載,一首一首的下載效率太慢了。所以,我們還要繼續(xù)尋找有沒有一個數據包,它的響應就包含了這首歌曲的鏈接。我的做法是將最后一個.mp3的名稱在數據包搜索欄中搜索對應關鍵字,很幸運,我找到了。
?


?接下來就非常簡單了,我們已經找到了每個要搜索的歌手的詳情網頁的規(guī)律(固定網址+歌手名字+.html),我們有獲取了每一首歌曲的詳情頁面(那一段沒有規(guī)律的英文字母),最后又在歌曲詳情頁面找到了包含歌曲鏈接的數據包,所以接下來我們要做的就是,將歌曲鏈接用二進制保存下來,學過爬蟲的同學應該注意到了,上面這個數據包的響應數json數據,返回的是一個字典形式的數據,我們可以根據鍵值對來取出我們需要的歌曲的下載鏈接。首先就是將這個給數據包根據對應的url請求下來,注意在請求頭中查看相應url的參數,代碼如下:
data = {'id': i,'type':?'music'}
? ?url2 =?'http://www.2t58.com/js/play.php'
? ?response2 = requests.post(url = url2,?headers = headers,?data = data)
? ?json_data = response2.json()
? ?musicList = json_data['url']
我們將歌曲的下載鏈接保存在列表musicList中,最后就是將歌曲保存,代碼如下:
musicResponse = requests.get(url = musicList)
? ?filename = json_data['title'] +?'.mp3'
? ?with?open('E:/music/'?+ filename,?'wb')?as?f:
? ? ? ?f.write(musicResponse.content)
? ? ? ?print(filename +?'下載成功!')
大家改一下路徑就可以正常運行了。
完整代碼:
import requests
import re
# 張學友:aHNj
# 陳奕迅:eG4
# 林憶蓮:d2t3eA
name = input()
url = 'http://www.2t58.com/so/{}/1.html'.format(name)
response = requests.get(url = url)
ex = '<div class="name"><a href="/song/(.*?).html" target="_mp3">.*?</a></div>'
musicIndex = re.findall(ex, response.text, re.S)
headers ={
'Accept':'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding':'gzip, deflate',
'Accept-Language':'zh-CN,zh;q=0.9',
'Connection':'keep-alive',
'Content-Length':'26',
'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
'Cookie':'Hm_lvt_b8f2e33447143b75e7e4463e224d6b7f=1690974946; Hm_lpvt_b8f2e33447143b75e7e4463e224d6b7f=1690976158',
'Host':'www.2t58.com',
'Origin':'http://www.2t58.com',
'Referer':'http://www.2t58.com/song/bWhzc3hud25u.html',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
'X-Requested-With':'XMLHttpRequest'
}
for i in musicIndex:
? ?data = {'id': i,'type': 'music'}
? ?url2 = 'http://www.2t58.com/js/play.php'
? ?response2 = requests.post(url = url2, headers = headers, data = data)
? ?json_data = response2.json()
? ?musicList = json_data['url']
? ?musicResponse = requests.get(url = musicList)
? ?filename = json_data['title'] + '.mp3'
? ?with open('E:/music/' + filename, 'wb') as f:
? ? ? ?f.write(musicResponse.content)
? ? ? ?print(filename + '下載成功!')
可能是因為網站不夠完善,有些歌手的詳情網頁并不是歌手名+.html,而是一些無規(guī)律的英文字母,我暫時發(fā)現(xiàn)的已經放在上面,如果要下載該歌手的歌曲,就輸入相應的英文字母。
僅供學習使用,請不要用于違法犯罪。