百萬年薪大佬熬夜寫作,Python高級編程之反爬蟲及應對方案


寫在前面

爬蟲是 Python 的一個常見應用場景,很多練習項目就是讓大家去爬某某網站
爬取網頁的時候,你大概率會碰到一些反爬措施
這種情況下,你該如何應對呢?
本文梳理了常見的反爬措施和應對方案
接着往下看吧

 

 

通過User-Agent來控制訪問

無論是瀏覽器還是爬蟲程序,在向服務器發起網絡請求的時候,都會發過去一個頭文件:headers
以本網頁為例,點擊鼠標右鍵,接着點擊[檢查],可以看到如下的示例

 

圖1

這里面的大多數的字段都是瀏覽器向服務表明身份用的
對於爬蟲程序來說,最需要注意的字段就是:User-Agent
很多網站都會建立User-Agent白名單,只有屬於正常范圍的user-agent才能夠正常訪問

解決方法

可以自己設置一下user-agent,或者更好的是,可以從一系列的user-agent里隨機挑出一個符合標准的使用

 

圖2

實現難度:★

IP限制

如果一個固定的ip在短暫的時間內,快速大量的訪問一個網站,后台管理員可以編寫IP限制,不讓該IP繼續訪問

解決方法

比較成熟的方式是:IP代理池

 

圖3

簡單的說,就是通過ip代理,從不同的ip進行訪問,這樣就不會被封掉ip了

可是ip代理的獲取本身就是一個很麻煩的事情,網上有免費和付費的,但是質量都層次不齊
如果是企業里需要的話,可以通過自己購買集群雲服務來自建代理池

實現難度:★

SESSION訪問限制

后台統計登錄用戶的操作,比如短時間的點擊事件,請求數據事件,與正常值比對,用於區分用戶是否處理異常狀態,如果是,則限制登錄用戶操作權限

但是這種訪問限制,需要增加數據埋點功能,閾值設置不好,容易造成誤操作

解決方法

注冊多個賬號、模擬正常操作

實現難度:★★★

Spider Trap

蜘蛛陷阱導致網絡爬蟲進入無限循環之類的東西,這會浪費蜘蛛的資源,降低其生產力,並且在編寫得不好的爬蟲的情況下,可能導致程序崩潰

禮貌蜘蛛在不同主機之間交替請求,並且不會每隔幾秒鍾從同一服務器請求多次文檔,這意味着“禮貌”網絡爬蟲比“不禮貌”爬蟲的影響程度要小得多

反爬方式

  1. 創建無限深度的目錄結構 HTTP://example.com/bar/foo/bar/foo/bar/foo/bar/
  2. 動態頁面,為網絡爬蟲生成無限數量的文檔。如由算法生成雜亂的文章頁面
  3. 文檔中填充了大量字符,使解析文檔的詞法分析器崩潰

此外,帶蜘蛛陷阱的網站通常都有robots.txt告訴機器人不要進入陷阱,因此合法的“禮貌”機器人不會陷入陷阱,而忽視robots.txt設置的“不禮貌”機器人會受到陷阱的影響

但是,反爬方式1,2會增加很多無用目錄或文件,造成資源浪費,也對正常的SEO十分不友好,可能會被懲罰

解決方法

把網頁按照所引用的css文件進行聚類,通過控制類里最大能包含的網頁數量防止爬蟲進入trap后出不來,對不含css的網頁會給一個penalty,限制它能產生的鏈接數量。這個辦法理論上不保證能避免爬蟲陷入死循環,但是實際上這個方案工作得挺好,因為絕大多數網頁都使用了css,動態網頁更是如此

實現難度:★★★

驗證碼

驗證碼是一種區分用戶是計算機還是人的公共全自動程序

可以防止:惡意破解密碼、刷票、論壇灌水,有效防止某個黑客對某一個特定注冊用戶用特定程序暴力破解方式進行不斷的登陸嘗試,實際上用驗證碼是現在很多網站通行的方式

1.圖片驗證碼

復雜型

 

圖4

打碼平台雇佣了人力,專門幫人識別驗證碼。識別完把結果傳回去。總共的過程用不了幾秒時間。這樣的打碼平台還有記憶功能。圖片被識別為“鍋鏟”之后,那么下次這張圖片再出現的時候,系統就直接判斷它是“鍋鏟”。時間一長,圖片驗證碼服務器里的圖片就被標記完了,機器就能自動識別了

簡單型

 

圖5

上面兩個不用處理直接可以用OCR識別技術(利用python第三方庫--esserocr)來識別

 

背景比較糊

 

清晰可見

經過灰度變換和二值化后,由模糊的驗證碼背景變成清晰可見的驗證碼

 

圖8

容易迷惑人的圖片驗證碼

對於在這種驗證碼,語言一般自帶圖形庫,添加上扭曲就成了這個樣子,我們可以利用9萬張圖片進行訓練,完成類似人的精准度,到達識別驗證碼的效果

2.短信驗證碼

打開手機,查看驗證碼(好像是廢話...)

3.計算題圖片驗證碼

 

圖9

把所有可能出現的漢字都人工取出來,保存為黑白圖片,把驗證碼按照字體顏色二值化,去除噪點,然后將所有圖片依次與之進行像素對比,計算出相似值,找到最像的那張圖片

4.滑動驗證碼

 

圖10

對於滑動驗證碼

我們可以利用圖片的像素作為線索,確定好基本屬性值,查看位置的差值,對於差值超過基本屬性值,我們就可以確定圖片的大概位置

5.圖案驗證碼

 

圖11

對於這種每次拖動的順序不一樣,結果就不一樣,我們怎么做來識別呢?

  • 利用機器學習所有的拖動順序,利用1萬張圖片進行訓練,完成類似人的操作,最終將其識別
  • 利用selenium技術來模擬人的拖動順序,窮盡所有拖動方式,這樣達到是別的效果

6.標記倒立文字驗證碼

 

圖12

我們不妨分析下:對於漢字而言,有中華五千年龐大的文字庫,加上文字的不同字體、文字的扭曲和噪點,難度更大了

方法:先點擊前兩個倒立的文字,可確定7個文字的坐標, 驗證碼中7個漢字的位置是確定的,只需要提前確認每個字所在的坐標並將其放入列表中,然后人工確定倒立文字的文字序號,將列表中序號對應的坐標即可實現成功登錄

悄悄的說一句,驗證碼越復雜,網站體驗感越差

實現難度:★★

通過robots.txt來限制爬蟲

robots.txt(統一小寫)是一種存放於網站根目錄下的ASCII編碼的文本文件,它通常告訴網絡搜索引擎的漫游器(又稱網絡蜘蛛),此網站中的哪些內容是不應被搜索引擎的漫游器獲取的,哪些是可以被漫游器獲取的

robots.txt協議並不是一個規范,而只是約定俗成的,所以並不能保證網站的隱私。注意robots.txt是用字符串比較來確定是否獲取URL,所以目錄末尾有與沒有斜杠“/”表示的是不同的URL

 

圖13

但是,這只是一個君子協議,對於良好的爬蟲比如搜索引擎有效果,對於有目的性的爬蟲不起作用

解決方法

如果使用scrapy框架,只需將settings文件里的ROBOTSTXT_OBEY設置值為 False

實現難度:★

數據動態加載

python的requests庫只能爬取靜態頁面,爬取不了動態加載的頁面
使用JS加載數據方式,能提高爬蟲門檻

解決方法

  • 抓包獲取數據url

通過抓包方式可以獲取數據的請求url,再通過分析和更改url參數來進行數據的抓取。
示例

一. 如下https://image.baidu.com 這部分的包。可以看到,這部分包里面,search下面的那個 url和我們訪問的地址完全是一樣的,但是它的response卻包含了js代碼

 

圖14

二. 當在動物圖片首頁往下滑動頁面,想看到更多的時候,更多的包出現了。從圖片可以看到,下滑頁面后得到的是一連串json數據。在data里面,可以看到thumbURL等字樣,它的值是一個url,這個就是圖片的鏈接

 

圖15

三.打開一個瀏覽器頁面,訪問thumbURL="
https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1968180540,4118301545&fm=27&gp=0.jpg" 發現搜索結果里的圖片

四.根據前面的分析,就可以知道,請求所需要的url

URL="https://image.baidu.com/search/acjsontn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E5%8A%A8%E7%89%A9%E5%9B%BE%E7%89%87&cl=2&lm=-1&ie=utf8&oe=utf8&adpicid=&st=-1&z=&ic=0&word=%E5%8A%A8%E7%89%A9%E5%9B%BE%E7%89%87&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&pn=30&rn=30&gsm=1e&1531038037275="

Python

復制

用瀏覽器訪問這個鏈接確定他是公開的

五.最后就可以尋找URL的規律,對URL進行構造便可獲取所有照片

  • 使用selenium

過使用selenium來實現模擬用戶操作瀏覽器,然后結合BeautifulSoup等包來解析網頁通過這種方法獲取數據,簡單,也比較直觀,缺點是速度比較慢

但是這種反爬方式如果數據API沒做加密處理,容易曝光接口,讓爬蟲用戶更容易獲取數據

實現難度:★

數據加密-使用加密算法

  • 前端加密
    通過對查詢參數、user-agent、驗證碼、cookie等前端數據進行加密生成一串加密指令,將加密指令作為參數,再進行服務器數據請求。該加密參數為空或者錯誤,服務器都不對請求進行響應
  • 服務器端加密
    在服務器端同樣有一段加密邏輯,生成一串編碼,與請求的編碼進行匹配,匹配通過則會返回數據

解決方法

JS加密破解方式,就是要找到JS的加密代碼,然后使用第三方庫js2py在Python中運行JS代碼,從而得到相應的編碼

案列參考:

https://blog.csdn.net/lsh19950928/article/details/81585881

實現難度:★★★

數據加密-使用字體文件映射

服務器端根據字體映射文件先將客戶端查詢的數據進行變換再傳回前端,前端根據字體文件進行逆向解密

映射方式可以是數字亂序顯示,這樣爬蟲可以爬取數據,但是數據是錯誤的

破解方式

其實,如果能看懂JS代碼,這樣的方式還是很容易破解的,所以需要做以下幾個操作來加大破解難度

  • 對JS加密
  • 使用多個不同的字體文件,然后約定使用指定字體文件方式,比如時間戳取模,這樣每次爬取到的數據映射方式都不一樣,映射結果就不一樣,極大提高了破解的難度

該種方式相比使用加密算法方式難度更高,因為加密算法是固定的幾種,對方很容易獲取並破解,而字體文件映射可以按任意規則映射,正常的數據使之錯誤顯示,爬蟲不容易察覺


免責聲明!

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



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