本文以爬取喜馬拉雅"三國演義-原文朗讀【四大名著】"一書為例,示範下Python爬蟲。
原書地址:http://www.ximalaya.com/4228109/album/268522/
1.進入地址我們可以發現,頁面有著非常整齊的目錄,那麼網頁原始碼中肯定也有非常規律的目錄,進去看看吧。
2.很明顯猜對了,原始碼中確實有這很明顯的規律,每一章節都有著及其固定的模板:
但是這時候我們並找不到深層的規律,那麼下一步我們嘗試下播放一條音頻,但不僅僅是播放,更重要的是要抓包。。。
3.開啟瀏覽器抓包工具(F12),點擊任意一條音頻,這裡我就以第一條為例了。
上面兩張圖是我抓取到的getURL和返回的json,可以看出返回的內容裡確實有三條音頻地址,複製到瀏覽器可以直接播放,聽一聽就是我們要的寶貝。重點來了,getURL中我圈出來的看著是不是很眼熟。不錯,那個就是網頁原始碼裡面每個章節URL裡的一個值,而這個值就是每個章節的sound_id,再按照上面的步驟,操作其他章節看看,也是一樣的規律。那麼思路很清晰了,我們只需要把每個章節的ID的sound_id替換到getURL中不就可以擷取到每個章節的音頻了麼。
4.開始寫代碼:
import requestsimport re#擷取網頁原始碼&解決反爬header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}html = requests.get('http://www.ximalaya.com/4228109/album/268522/',headers=header)print(html.text)reg = '<a class="title" href="/4228109/sound/(.*?)/" hashlink title="(.*?)">'name_url = re.findall(reg,html.text)print(name_url)
這個時候我們可以看到,網頁每個章節和對應sound_id都被找出來了。
5.返回的有沒有很亂。確實很亂,但是返回的都是元群組類型,那麼我們來定義一個ID和標題吧。
for sound_id,title in name_url: print(sound_id,title)
看下效果,有沒有耳目一新:
6.好了,回到最開始我們抓包的時候,我們的音頻都在一個抓取的json裡,開始拼接咱們的json URL
json_url = 'http://www.ximalaya.com/tracks/'+str(sound_id)+'.json' print(title,json_url)
7.既然已經擷取到了每個URL,那麼現在去json裡面取最終的音頻URL吧
首先去請求下每個音訊json URL,然後配對出最終的URL吧
#擷取每個音訊json URL json_url = 'http://www.ximalaya.com/tracks/'+str(sound_id)+'.json' # print(json_url) result = requests.get(json_url,headers=header) reg1 = '"play_path_64":"(.*?)"' #最終的音頻URL數列 sound_url = re.findall(reg1,result.text) #列印音頻URL數列 print(title,sound_url)
8.好了,URL都拿到了,可以去下載了。。。
最後,貼上完整代碼:
import requestsimport reimport time#擷取網頁原始碼&解決反爬header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}html = requests.get('http://www.ximalaya.com/4228109/album/268522/',headers=header)# print(html.text)reg = '<a class="title" href="/4228109/sound/(.*?)/" hashlink title="(.*?)">'name_url = re.findall(reg,html.text)# print(name_url)for sound_id,title in name_url: # print(sound_id,title) #擷取每個音訊json URL json_url = 'http://www.ximalaya.com/tracks/'+str(sound_id)+'.json' # print(json_url) #正則匹配出ID和音頻URL result = requests.get(json_url,headers=header) reg1 = '"play_path_64":"(.*?)"' #最終的音頻URL數列 sound_url = re.findall(reg1,result.text) #列印音頻URL數列 # print(sound_url) # print(title,sound_url[0]) data = requests.get(sound_url[0]) with open(title+'.m4a','wb') as f: f.write(data.content) print('下載完成:',title) time.sleep(1)