天天看點

【Python3爬蟲】常見反爬蟲措施及解決辦法(二)一、防盜鍊二.随機化網頁源碼

【Python3爬蟲】常見反爬蟲措施及解決辦法(二)

這一篇部落格,還是接着說那些常見的反爬蟲措施以及我們的解決辦法。同樣的,如果對你有幫助的話,麻煩點一下推薦啦。

一、防盜鍊

這次我遇到的防盜鍊,除了前面說的Referer防盜鍊,還有Cookie防盜鍊和時間戳防盜鍊。Cookie防盜鍊常見于論壇、社群。當訪客請求一個資源的時候,他會檢查這個訪客的Cookie,如果不是他自己的使用者的Cookie,就不會給這個訪客正确的資源,也就達到了防盜的目的。時間戳防盜鍊指的是在他的url後面加上一個時間戳參數,是以如果你直接請求網站的url是無法得到真實的頁面的,隻有帶上時間戳才可以。

這次的例子是天涯社群的

圖檔分社群

【Python3爬蟲】常見反爬蟲措施及解決辦法(二)一、防盜鍊二.随機化網頁源碼

這裡我們先打開開發者工具,然後任意選擇一張圖檔,得到這個圖檔的連結,然後用requests來下載下傳一下這張圖檔,注意帶上Referer字段,看結果如何:

import requests

url = "http://img3.laibafile.cn/p/l/305989961.jpg"
headers = {
    "Referer": "http://pp.tianya.cn/",
    "UserAgent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36"
}
res = requests.get(url)
with open('test.jpg', 'wb') as f:
    f.write(res.content)      

我們的爬蟲正常運作了,也看到生成了一個test.jpg檔案,先别急着高興,打開圖檔看一下:

【Python3爬蟲】常見反爬蟲措施及解決辦法(二)一、防盜鍊二.随機化網頁源碼

一口老血吐了出來,竟然還有這種套路!怎麼辦呢?往下看!

解決辦法:

既然他說僅供天涯社群使用者分享,那我們也成為他的使用者不就行了嗎?二話不說就去注冊了個賬号,然後登入,再拿到登入後的Cookie:

__auc=90d515c116922f9f856bd84dd81; Hm_lvt_80579b57bf1b16bdf88364b13221a8bd=1551070001,1551157745; user=w=EW2QER&id=138991748&f=1; right=web4=n&portal=n; td_cookie=1580546065; __cid=CN; Hm_lvt_bc5755e0609123f78d0e816bf7dee255=1551070006,1551157767,1551162198,1551322367; time=ct=1551322445.235; __asc=9f30fb65169320604c71e2febf6; Hm_lpvt_bc5755e0609123f78d0e816bf7dee255=1551322450; __u_a=v2.2.4; sso=r=349690738&sid=&wsid=71E671BF1DF0B635E4F3E3E41B56BE69; temp=k=674669694&s=&t=1551323217&b=b1eaa77438e37f7f08cbeffc109df957&ct=1551323217&et=1553915217; temp4=rm=ef4c48449946624e9d7d473bc99fc5af; u_tip=138991748=0      

注意:Cookie是有時效性的,具體多久就會失效我沒測試。緊接着把Cookie添加到代碼中,然後運作,可以看到成功把圖檔下載下傳下來了:

【Python3爬蟲】常見反爬蟲措施及解決辦法(二)一、防盜鍊二.随機化網頁源碼

搞了這麼久才下了一張圖檔,我們怎麼可能就這麼滿足呢?分析頁面可知一個頁面上有十五張圖檔,然後往下拉的時候會看到"正在加載,請稍後":

【Python3爬蟲】常見反爬蟲措施及解決辦法(二)一、防盜鍊二.随機化網頁源碼

我們立馬反應過來這是通過AJAX來加載的,于是打開開發者工具檢視,可以找到如下内容:

【Python3爬蟲】常見反爬蟲措施及解決辦法(二)一、防盜鍊二.随機化網頁源碼

可以看到每個連結“?”前面的部分都是基本一樣的,“list_”後面跟的數字表示頁數,而“_=”後面這一串數字是什麼呢?有經驗的人很快就能意識到這是一個時間戳,是以我們來測試一下:

import time
import requests

t = time.time()*1000
url = "http://pp.tianya.cn/qt/list_4.shtml?_={}".format(t)
res = requests.get(url)
print(res.text)      

 運作之後得到了我們想要的結果。現在我們已經能用代碼構造連結了,那我們怎麼知道最多有多少頁呢?我們先繼續拖動滾輪下拉頁面,發現出現第5頁之後就沒有了:

【Python3爬蟲】常見反爬蟲措施及解決辦法(二)一、防盜鍊二.随機化網頁源碼

這怎麼辦呢?不急,我們不是已經能自己構造連結了嘛,我們可以通過改變“list”後面的數字來得到更多的頁面啊。不過我自己測試的結果是最多隻有15頁,之後再怎麼增大數字也沒用了,應該是伺服器做了限制,最多隻給15頁的資料。下圖是我把數字改為16後傳回的結果:

【Python3爬蟲】常見反爬蟲措施及解決辦法(二)一、防盜鍊二.随機化網頁源碼

最後編寫程式并運作,就能把圖檔下載下傳下來了:

【Python3爬蟲】常見反爬蟲措施及解決辦法(二)一、防盜鍊二.随機化網頁源碼

完整代碼已上傳到

GitHub

二.随機化網頁源碼

用display:none來随機化網頁源碼,有網站還會随機類和id的名字,然後再加點随機的tr和td,這樣的話就增大了我們解析的難度。比如

全網代理IP
【Python3爬蟲】常見反爬蟲措施及解決辦法(二)一、防盜鍊二.随機化網頁源碼

可以看到每個IP都是包含在一個class為“ip”的td裡的,是以我們可以先定位到這個td,然後進行下一步解析。雖然這個td裡面包含了很多的span标簽和p标簽,而且也每個标簽的位置也沒有什麼規律,不過還是有辦法解析的。方法就是把這個td裡的所有文字提取出來,然後把那些前後重複的部分去除掉,最後拼接到一起就可以了,代碼如下:

1 et = etree.HTML(html)  # html:網頁源碼
2 for n in range(1, 21):
3     lst = et.xpath('//table/tbody/tr[{}]/td[1]//text()'.format(n))
4     proxy = ""
5     for i in range(len(lst) - 1):
6         if lst[i] != lst[i + 1]:
7             proxy += lst[i]
8     proxy += lst[-1]
9     print(proxy)      

最後就能得到我們想要的資料了。不過我們得到的端口資料和網頁上顯示的資料是不一樣的,這是因為端口資料是經過了JS混淆的,至于怎麼破解,下次會分享出來。

 原文位址

https://www.cnblogs.com/TM0831/p/10436608.html