Python爬蟲進階:爬取梨視訊網站Top排行榜視訊資料
本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯絡我們以作處理
以下文章來源於青燈程式設計 ,作者:清風
Python爬蟲進階:反反爬實戰案例—爬取梨視訊,觀看地址:
https://www.bilibili.com/video/BV1mK4y1E75Y/
前言
關於梨視訊的爬取,網站上面還是有很多教程文章的,但是之前的那些教程文章統統都不能實現了,因為梨視訊網站早就更新了。之前也有很多小夥伴也在問關於該網站的爬取方法。
基本開發環境
- Python 3.6
- Pycharm
相關模組的使用
import requests importre import threading
目標網頁分析
單個視訊地址獲取
點選進入第一個視訊的詳情頁,使用開發者工具可以找到相關的視訊地址。
https://video.pearvideo.com/mp4/adshort/20201221/1608712845841-15540331_adpkg-ad_hd.mp4
連結中的contId對應的就是視訊的ID
defget_video_url(video_id):
data_url='https://www.pearvideo.com/videoStatus.jsp?contId={}&mrd=0.5606814943122209'.format(video_id)
headers_1={
'Referer':'https://www.pearvideo.com/video_{}'.format(video_id),
'User-Agent':'Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/81.0.4044.138Safari/537.36'
}
response=requests.get(url=data_url,headers=headers_1)
html_data=response.json()
video_url=html_data['videoInfo']['videos']['srcUrl']
suffix=video_url.split('-')[1]
date=video_url.split('/')[-2]
new_url='https://video.pearvideo.com/mp4/adshort/{}/cont-{}-{}-ad_hd.mp4'.format(date,video_id,suffix)
returnnew_url
注意點:
1、headers 請求頭一定要新增Referer防盜鏈 , 不然獲取不到資料 。
2、這裡獲取的視訊url地址,並非真實的url地址,複製連結會發現是404
#資料介面獲取的視訊地址
'''
https://video.pearvideo.com/mp4/adshort/20201222/1608723660585-15542059_adpkg-ad_hd.mp4
'''
#真實的視訊播放地址
'''
https://video.pearvideo.com/mp4/adshort/20201222/cont-1712976-15542059_adpkg-ad_hd.mp4
'''
所以需要拼接一下url
獲取視訊ID
根據資料介面url 可知,只要獲取每個視訊的ID值,就可以爬取所有的視訊了。
這就需要在排行榜列表中查找了。
如上圖所示,視訊排行榜頁面有我們需要的視訊ID值,但是這隻有一個10個視訊地址呀,需要網頁往下滑動才可以檢視更多的內容。所以老辦法,先清空開發者工具裡面的資料,然後下滑網頁。
於是乎就出現了很多的相關資料。經過分析對比。
可以發現其中是有兩個引數發現改變的:
start:等差數列,每次增加10
sort:9、14、21、29、38、46、54、62、69、74 每次變化沒有規律
那這樣我只能讓不規律的哪個引數保持不變,給一個恆定值9,然後根據start的引數給改變,看是否能夠獲取資料,咱們就以不變應萬變。
當URL中start=0時
可以看出,最後一個視訊是<2020回聲:50段現場聲音回顧這一年>,在排行榜當中應該是屬於 第9個的位置,但是這裡的序號是18.
當URL中sort=10時
第一個視訊是<被害者家屬談勞榮枝案首日庭審>,在排行榜當中應該是屬於 第10個的位置,剛好是接著上面的視訊往下排的。。
當URL中sort=20時
同樣的是接著排下來的。
所以只需要改變sort這個引數即可獲取排行榜所有的視訊ID以及視訊標題。
defget_video_id(page_url):
html_data=get_response(page_url).text
video_ids=re.findall('<ahref="video_(\d+)"class="actplay">',html_data)
title=re.findall('<h2class="popularem-title">(.*?)</h2>',html_data)
video_info=zip(video_ids,title)
foriinvideo_info:
video_title=i[1]
video_id=i[0]
儲存資料
defsave(video_url,video_title):
video_content=get_response(video_url).content
filename='video\\'+video_title+'.mp4'
withopen(filename,mode='wb')asf:
f.write(video_content)
print('正在儲存:',video_title)
當儲存的時候出現了報錯。
因為標題中出現特殊字元,沒有辦法儲存。
之前有說過,當你新建檔案的時候,檔案命名中出現特殊字元是沒有辦法命名建立的,所以需要使用正則表示式,替換掉標題中的特殊字元。
defchange_title(title):
pattern=re.compile(r"[\/\\\:\*\?\"\<\>\|]")#'/\:*?"<>|'
new_title=re.sub(pattern,"_",title)#替換為下劃線
returnnew_title
完整實現程式碼
importrequests
importre
importthreading
headers={
'User-Agent':'Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/81.0.4044.138Safari/537.36'
}
defget_response(html_url):
response=requests.get(url=html_url,headers=headers)
returnresponse
defchange_title(title):
pattern=re.compile(r"[\/\\\:\*\?\"\<\>\|]")#'/\:*?"<>|'
new_title=re.sub(pattern,"_",title)#替換為下劃線
returnnew_title
defsave(video_url,video_title):
video_content=get_response(video_url).content
filename='video\\'+video_title+'.mp4'
withopen(filename,mode='wb')asf:
f.write(video_content)
print('正在儲存:',video_title)
print(video_url)
defget_video_url(video_id):
data_url='https://www.pearvideo.com/videoStatus.jsp?contId={}&mrd=0.5606814943122209'.format(video_id)
headers_1={
'Referer':'https://www.pearvideo.com/video_{}'.format(video_id),
'User-Agent':'Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/81.0.4044.138Safari/537.36'
}
response=requests.get(url=data_url,headers=headers_1)
html_data=response.json()
video_url=html_data['videoInfo']['videos']['srcUrl']
suffix=video_url.split('-')[1]
date=video_url.split('/')[-2]
new_url='https://video.pearvideo.com/mp4/adshort/{}/cont-{}-{}-ad_hd.mp4'.format(date,video_id,suffix)
returnnew_url
defmain(page_url):
html_data=get_response(page_url).text
video_ids=re.findall('<ahref="video_(\d+)"class="actplay">',html_data)
title=re.findall('<h2class="popularem-title">(.*?)</h2>',html_data)
video_info=zip(video_ids,title)
foriinvideo_info:
video_title=i[1]
video_id=i[0]
video_url=get_video_url(video_id)
new_title=change_title(video_title)
save(video_url,new_title)
if__name__=='__main__':
forpageinrange(0,101,10):
url='https://www.pearvideo.com/popular_loading.jsp?reqType=1&categoryId=&start={}&sort=9&mrd=0.9278261602425337'.format(page)
main_thread=threading.Thread(target=main,args=(url,))
main_thread.start()
排行榜一共是74條資料。。。。。。