Python中使用requests和parsel爬取喜马拉雅电台音频
場(chǎng)景
喜馬拉雅電臺(tái):
https://www.ximalaya.com/
找到一步小說(shuō)音頻,這里以下面為例
https://www.ximalaya.com/youshengshu/16411402/
博客:
https://blog.csdn.net/badao_liumang_qizhi
關(guān)注公眾號(hào)
霸道的程序猿
獲取編程相關(guān)電子書、教程推送與免費(fèi)下載。
實(shí)現(xiàn)
找到下載地址
使用谷歌瀏覽器打開(kāi)上面網(wǎng)址,按F12打開(kāi)調(diào)試,點(diǎn)擊播放按鈕后,然后找到Network下的Media下的Headers下的RequestURL,然后選中在新窗口中打開(kāi)
?
打開(kāi)之后就可以點(diǎn)擊三個(gè)點(diǎn)出來(lái)之后的下載按鈕,便可以下載
?
使用代碼下載
打開(kāi)PyCharm,新建一個(gè)Python項(xiàng)目
導(dǎo)入requests庫(kù),然后為了防止其反扒機(jī)制,找到瀏覽器上Headers下的Requests Headers下的User-Agent,復(fù)制出來(lái)。
#能發(fā)送http請(qǐng)求的庫(kù) import requestsheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36' }media_url = 'http://audio.cos.xmcdn.com/group47/M0A/34/EA/wKgKm1tHj6GwgeWBAFehkfjyvKI181.m4a'response = requests.get(media_url,headers = headers);with open('badao.mp4',mode='wb') as f:f.write(response.content)下載成功之后
?
下載地址獲取
上面只是獲取一個(gè)音頻的下載地址,怎樣獲取每一集的下載地址
還是剛才的調(diào)試頁(yè)面,我們點(diǎn)擊放大鏡樣的搜索按鈕,出來(lái)搜索框之后,輸入剛才下載地址的文件名
點(diǎn)擊第一個(gè)返回json數(shù)據(jù)的接口url,找到其Headers下的RequestURL。
?
然后在新窗口打開(kāi)
?
可以看到是通過(guò)這個(gè)API返回的Json數(shù)據(jù)中的下載地址。
那么這個(gè)API需要傳遞什么參數(shù)。通過(guò)其Headers底部的請(qǐng)求參數(shù)可以看到需要一個(gè)id參數(shù)和pytype參數(shù)。
?
通過(guò)對(duì)比每一集的接口的請(qǐng)求參數(shù)得知,pytype是固定的,id是每一集對(duì)應(yīng)的鏈接中的id相對(duì)應(yīng)的。
?
所以要是循環(huán)下載多集的話,需要在目錄頁(yè)面獲取超鏈接的href屬性中對(duì)應(yīng)的id。
?
這里我們定義一個(gè)請(qǐng)求下載地址json數(shù)據(jù)的方法
def media_api(track_id):api_url=f'https://www.ximalaya.com/revision/play/v1/audio?id={track_id}&ptype=1';response = requests.get(api_url,headers = headers)print(response.json())media_api(98791745)運(yùn)行下打印json數(shù)據(jù)
?
提取下載地址
那么就需要根據(jù)傳遞的id參數(shù)通過(guò)這個(gè)接口返回json數(shù)據(jù),并從json數(shù)據(jù)中提取src對(duì)應(yīng)的url數(shù)據(jù)
defmedia_api(track_id):api_url=f'https://www.ximalaya.com/revision/play/v1/audio?id={track_id}&ptype=1';response = requests.get(api_url,headers = headers)#print(response.json())#json返回字典類型? 提取使用[]data_json = response.json()src = data_json['data']['src']return srcmedia_api(98791745)這樣就能根據(jù)id獲取每一集的下載地址,然后再將下載地址傳遞給上面第一步下載的方法中進(jìn)行下載即可。
接下來(lái)就是怎樣獲取每一集的id。
parsel解析網(wǎng)頁(yè)獲取id
首先需要導(dǎo)入parsel模塊
import parsel如果沒(méi)有安裝則需要安裝
pip install parsel?
我們來(lái)到其目錄頁(yè)
?
在Elemnts下可以看到每一集是一個(gè)a標(biāo)簽,我們獲取a標(biāo)簽的href屬性中的最后面的id。
我們?cè)俣x一個(gè)方法,此方法能根據(jù)頁(yè)面的url獲取當(dāng)前頁(yè)的所有集的id。
def get_total_page(page_url):#請(qǐng)求頁(yè)面response = requests.get(page_url,headers = headers)print(response.text)#獲取頁(yè)面html的內(nèi)容sel = parsel.Selector(response.text)print(sel)#通過(guò)css選擇器找到a標(biāo)簽?? .sound-list代表 class屬性為sound-list 然后下面的ul 下的li 下的asound_list = sel.css('.sound-list ul li a')print(sound_list)#只有前30個(gè)是頁(yè)面鏈接 截取前30個(gè)for sound in sound_list[:30]:#extract_first()將對(duì)象中的文字提取出來(lái)#獲取a標(biāo)簽的href屬性的內(nèi)容media_url = sound.css('a::attr(href)').extract_first()#/youshengshu/16411402/98791745 --只去最后面的idmedia_url = media_url.split('/')[-1]# 獲取a標(biāo)簽的title屬性的內(nèi)容media_name = sound.css('a::attr(title)').extract_first()#用yield將整個(gè)循環(huán)的內(nèi)容返回yield media_url,media_name下載一頁(yè)的音頻
我們?cè)趍ain方法中調(diào)用獲取當(dāng)前頁(yè)所有的集的id和名字,然后循環(huán)將拿到的id去請(qǐng)求api獲取下載的地址,然后將下載地址傳遞給下載的方法去下載
if __name__ == '__main__':meidas = get_total_page('https://www.ximalaya.com/youshengshu/16411402/')for media_id,media_name in meidas:#print(media_url, media_name)media_url = media_api(media_id)download_meida(media_url, media_name)運(yùn)行程序?qū)⒁豁?yè)下載完
?
下載所有頁(yè)
我們點(diǎn)擊第二頁(yè)看到url中追加了一個(gè)p2,依次類推,p+相應(yīng)的頁(yè)數(shù)。
這樣就可以將頁(yè)面url改造成傳參的
if __name__ == '__main__':#循環(huán)頁(yè)數(shù)下載 range代表下載的頁(yè)數(shù)范圍for page in range(2,3):meidas = get_total_page(f'https://www.ximalaya.com/youshengshu/16411402/p{page}')for media_id,media_name in meidas:#print(media_url, media_name)media_url = media_api(media_id)download_meida(media_url, media_name)?
那么在range中就可以輸入要下載的頁(yè)數(shù)的范圍。
如果輸入(1,31)就是下載所有的30頁(yè),這里只下載第二頁(yè),所以range是(2,3)
代碼下載
關(guān)注公眾號(hào):
霸道的程序猿
回復(fù):
爬取喜馬拉雅
?
?
?
總結(jié)
以上是生活随笔為你收集整理的Python中使用requests和parsel爬取喜马拉雅电台音频的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 从实例一步一步入门学习SpringClo
- 下一篇: 史上最全Winform中使用ZedGra