前言
我們在上一節(jié)學(xué)習(xí)了一些的進(jìn)階用法和會話的概念以及很多安全校驗(yàn)信息。那么這一節(jié)我們將以某視頻網(wǎng)站(鏈接在評論區(qū))為例,展示一下我們的學(xué)習(xí)成果。
目的
抓取某視頻網(wǎng)站已知頁面所包含的視頻資源并保存到本地,繞過網(wǎng)站的反爬手段:防盜鏈。
思路
1. 首先打開想要抓取的頁面用代碼提取網(wǎng)頁視頻,檢查頁面源代碼,利用我們熟悉的開發(fā)者工具(F12)來檢查視頻資源所在的標(biāo)簽,可以通過下圖所示源代碼輕松找到:
2. 把src里面包含的視頻鏈接復(fù)制,訪問頁面觀察是不是視頻資源:
可以看到,我們成功拿到了視頻資源。但是我們真的成功了嗎?檢查頁面源代碼,我們拿到的頁面源代碼里面有這樣的標(biāo)簽嗎?或者是否在源代碼中存在我們的視頻鏈接呢?
3. 源代碼驗(yàn)證
我們查看頁面源代碼,CTRL+F查找,發(fā)現(xiàn)并沒有上述資源:
實(shí)際上,我們使用開發(fā)者工具檢查頁面時(shí),它所顯示的"源代碼"并不是原本的,而是已經(jīng)通過了一系列的解析,呈現(xiàn)給我們所看到整個(gè)頁面的資源信息。如果我們用直接訪問的話,是拿不到經(jīng)處理的標(biāo)簽的,所以這樣抓視頻鏈接是行不通的。但至少我們已經(jīng)知道了我們想拿到的目標(biāo)鏈接是什么了。
4. 開發(fā)者工具檢查網(wǎng)絡(luò)請求
打開開發(fā)者工具,切換到網(wǎng)絡(luò)() ,篩選選項(xiàng)到Fetch/XHR上。所謂XHR就是,是瀏覽器提供的對象,通過它,可以請求服務(wù)器上的數(shù)據(jù)資源。所以我們切換到這個(gè)篩選項(xiàng),因?yàn)樵创a里面沒有,一般就一定在js對象中請求。
5. 打開上述請求進(jìn)行檢查,進(jìn)行預(yù)覽,一層層解開json數(shù)據(jù),找到請求鏈接:
6. 訪問此鏈接,查看是否能請求到視頻資源:
7. 發(fā)現(xiàn)無法訪問,那么我們來對比兩個(gè)鏈接的不同之處:
正確的:https://video.某某video.com/mp4/adshort/20180420/cont-1328058-11924608_adpkg-ad_hd.mp4
錯(cuò)誤的:https://video.某某video.com/mp4/adshort/20180420/1672821168882-11924608_adpkg-ad_hd.mp4
對比發(fā)現(xiàn),只有‘cont-’與‘82’的區(qū)別。那么我們只要搞清楚這兩項(xiàng)分別是什么,再進(jìn)行替換就OK了。
8. 查找兩項(xiàng)的含義
發(fā)現(xiàn)‘cont-’后面的一串?dāng)?shù)字就是我們訪問頁面下劃線后的那串?dāng)?shù)字!
發(fā)現(xiàn)‘82’就是我們抓取到j(luò)son數(shù)據(jù)中的‘’!
現(xiàn)在思路就十分清晰了,直接進(jìn)入代碼部分。
代碼實(shí)現(xiàn) 第一步,理清思路,導(dǎo)包
# 1. 從鏈接拿到contId

# 2. 拿到videoStatus返回的json找到srcURL
# 3. 對srcURL里面的內(nèi)容進(jìn)行替換
# 4. 下載視頻
import requests
第二步,拉取視頻網(wǎng)址,拿到,獲取請求視頻的json網(wǎng)址
# 拉取視頻的網(wǎng)址
url = "見評論區(qū)"
contId = url.split("_")[1]
熟悉基礎(chǔ)的同學(xué)應(yīng)該知道split()是把目標(biāo)字符串分成兩部分,我們要的是下劃線的后半部分,所以拿[1]。
現(xiàn)在我們拿到了這部分,后面的mrd應(yīng)該是一個(gè)自動(dòng)生成的隨機(jī)數(shù)用代碼提取網(wǎng)頁視頻,不用管它也可以。
生成普適的視頻資源請求:
videoStatusUrl = f"https://www.某某video.com/videoStatus.jsp?contId={contId}"
第三步,嘗試訪問頁面,添加安全信息
從請求標(biāo)頭中可以拿到UA,而我們只將UA放入中時(shí)是訪問不到頁面的,這是由于的原因。
本章重點(diǎn):
它就是我們一直在說的防盜鏈:,功能就是溯源,告訴服務(wù)器當(dāng)前請求的上一級是誰?也就是從哪個(gè)頁面跳轉(zhuǎn)訪問的。服務(wù)器會拒絕非頁面跳轉(zhuǎn)的訪問,既然他要,那我們在里面也聲明一下就好了。
第四步,裝飾請求頭,獲取信息
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36",
# 防盜鏈: 溯源, 當(dāng)前本次請求的上一級是誰
"Referer": url
}
resp = requests.get(videoStatusUrl, headers=headers)
dic = resp.json()
觀察到防盜鏈就是我們最初的頁面,那么直接把防盜鏈設(shè)置成它就好。
由于返回的是json文件,我們對它進(jìn)行resp.json()的處理。
第五步,獲取獲取視頻資源的Url并對關(guān)鍵信息進(jìn)行替換
srcUrl = dic['videoInfo']['videos']['srcUrl']
systemTime = dic['systemTime']
srcUrl = srcUrl.replace(systemTime, f"cont-{contId}")
第六步,下載視頻
# 下載視頻
with open("3_result.mp4", mode="wb") as f:
f.write(requests.get(srcUrl).content)
完整代碼
# 1. 拿到contId
# 2. 拿到videoStatus返回的json. -> srcURL
# 3. srcURL里面的內(nèi)容進(jìn)行修整
# 4. 下載視頻
import requests
# 拉取視頻的網(wǎng)址
url = "見評論區(qū)"
contId = url.split("_")[1]
videoStatusUrl = f"https://www.某某video.com/videoStatus.jsp?contId={contId}"
headers = {

"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36",
# 防盜鏈: 溯源, 當(dāng)前本次請求的上一級是誰
"Referer": url
}
resp = requests.get(videoStatusUrl, headers=headers)
dic = resp.json()
srcUrl = dic['videoInfo']['videos']['srcUrl']
systemTime = dic['systemTime']
srcUrl = srcUrl.replace(systemTime, f"cont-{contId}")
# 下載視頻
with open("3_result.mp4", mode="wb") as f:
f.write(requests.get(srcUrl).content)
總結(jié)
我們對的進(jìn)階用法進(jìn)行了實(shí)踐,并且熟悉了網(wǎng)頁開發(fā)者工具的使用功能,“破解”了網(wǎng)站的防盜鏈,進(jìn)行了一個(gè)反反爬操作。