爬蟲學習之視頻爬取


錯誤寫法

如果我們用xpath爬取視頻,只需要檢閱元素,


我們會查找到視頻地址,理論上會直接獲取到,但結果返回的是空列表:

我們直接看頁面源代碼,搜索<video,結果是查找不到的,這是因為頁面源代碼是固定好的,而整個頁面是不斷更新的,因此多是用json寫的,在開發者模式下, 元素是基於頁面源代碼動態更新的。
傳統的網頁(不使用 AJAX)如果需要更新內容,必需重載整個網頁面。自從有了ajax之后,我們就可以實現異步的加載網頁。
什么叫異步?
異步,異嘛,不同的意思,這里也就是指不跟瀏覽器加載執行網頁代碼的步伐一致,也就是說在一個網頁中需要用戶操作來觸發執行代碼,而不是整個網頁代碼一次性執行完畢。(這里的用戶操作是指在同一個網頁下面請求代碼執行渲染,而不是讓瀏覽器直接跳轉渲染另一個頁面)
詳細解釋看這里
因此這種寫法是獲取不到視頻鏈接的

正確寫法:

我們先看一下視頻鏈接:

在開發者模式下,點擊XHR(相當於一個接口,通過這個接口,我們可以對網站進行更新而不需要更改頁面源代碼,這就是為什么有的內容我們在頁面源代碼查找不到),我們會看到一個json文件:

最底層有一個關於video的srcurl
我們將這個srcurl打開,結果是404。
對比一下下面的兩個鏈接:

只需要將"20211112/"到"-15192550"之間的替換即可,那么替換的部分我們會發現,就是systemtime

因此我們通過請求這個json文件的url獲取

報錯


常規請求:url,headers=headers
但返回的結果是:

我們向下翻,會看到Referer:

這是一個防盜鏈,比如說目錄是1->2->3,如果消失,我們就無法從3溯源到1,因此,我們要在headers里加一個Referer,注意headers是一個字典,添加要有,連接,這樣我們就能夠獲取到需要的信息了

獲取信息並處理

我們返回json字典形式,並獲取systemTimesrcUrl

videoStatusurl = "https://www.pearvideo.com/videoStatus.jsp?contId=1745747&mrd=0.878842147502072"
req = requests.get(videoStatusurl,headers=headers)

# json 返回字典 尋找需要的url
dic = req.json()
srcurl = dic['videoInfo']['videos']['srcUrl']
systemtime = dic['systemTime']

獲取srcUrl 后,將srcurl中的systemTime替換成contId:

contId 是視頻的地址后面的數字,也等同於XHR下json文件的Payload
接下來將contId把systemTime替換掉就可:

# 以 f開頭表示在字符串內支持大括號內的python 表達式
#srcurl = srcurl.replace(systemtime,"cont-"+contId)
srcurl = srcurl.replace(systemtime,f"cont-{contId}")

完整代碼:

code:

# 在頁面元素中可以查找到,但在頁面源代碼找不到視頻,
# 這是后期通過js腳本加入的,因此在xpath會返回空列表
# 開發者工具是實時的,頁面源代碼是固定好的源代碼

import re
import requests
import time
from xml import etree

# 獲取contid
# 拿到videostatus 返回的json. -> srcURL
# srcURL 修改調整
# 下載視頻

#獲取視頻網址
url = "https://www.pearvideo.com/video_1745747"
contId = url.split('_')[1]

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36 Edg/96.0.1054.29'
    # Referer 防盜鏈 : 1->2->3 2消失無法溯源,Referfer 可以溯源
    # 字典加,
    ,'Referer': 'https://www.pearvideo.com/video_1745747'
    # 'Referer': url 也可
}


videoStatusurl = "https://www.pearvideo.com/videoStatus.jsp?contId=1745747&mrd=0.878842147502072"
req = requests.get(videoStatusurl,headers=headers)

# json 返回字典 尋找需要的url
dic = req.json()
srcurl = dic['videoInfo']['videos']['srcUrl']
systemtime = dic['systemTime']

# 以 f開頭表示在字符串內支持大括號內的python 表達式
#srcurl = srcurl.replace(systemtime,"cont-"+contId)
srcurl = srcurl.replace(systemtime,f"cont-{contId}")

with open("梨視頻.mp4",'wb') as f:
    f.write(requests.get(srcurl).content)
print("over")
req.close()



#https://video.pearvideo.com/mp4/third/20211112/cont-1745747-15192550-115119-hd.mp4
#https://video.pearvideo.com/mp4/third/20211112/1637635409563-15192550-115119-hd.mp4


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM