隨著 Python 和大數(shù)據(jù)的火熱,大量的工程師蜂擁而上仅醇,爬蟲技術(shù)由于易學(xué)冗美、效果顯著首當(dāng)其沖的成為了大家追捧的對(duì)象,爬蟲的發(fā)展進(jìn)入了高峰期析二,因此給服務(wù)器帶來(lái)的壓力則是成倍的增加粉洼。企業(yè)或?yàn)榱吮WC服務(wù)的正常運(yùn)轉(zhuǎn)或?yàn)榱私档蛪毫εc成本节预,不得不使出各種各樣的技術(shù)手段來(lái)阻止爬蟲工程師們毫無(wú)節(jié)制的向服務(wù)器索取資源,我們將這種行為稱為『反爬蟲』属韧。
『反爬蟲技術(shù)』是互聯(lián)網(wǎng)技術(shù)中為了限制爬蟲而產(chǎn)生的技術(shù)總稱,而反爬蟲的繞過(guò)則是所有爬蟲工程師要面對(duì)的問(wèn)題宵喂,也是中高級(jí)爬蟲工程師面試中最關(guān)注的方面糠赦。
問(wèn)題所在
但是在平時(shí)的交流中锅棕,筆者發(fā)現(xiàn)大多數(shù)的初級(jí)爬蟲工程師只會(huì)拿著網(wǎng)上別人寫的技術(shù)文章唾沫橫飛拙泽,除了知道在請(qǐng)求的時(shí)候偽造瀏覽器請(qǐng)求頭信息中的 User-Agent 以外,對(duì)于:
- 為什么要這么做裸燎?
- 這么做有什么好處顾瞻?
- 我可以用別的方法實(shí)現(xiàn)么?
- 它的原理是怎么樣的顺少?
- 它是如何識(shí)別我的爬蟲的朋其?
- 我應(yīng)該用什么方式繞過(guò)它?
一無(wú)所知脆炎。如果你既不知道原理又不知道實(shí)現(xiàn)方式梅猿,那么當(dāng)目標(biāo)網(wǎng)站稍微調(diào)整一下反爬蟲策略的時(shí)候,你還是一臉懵逼
對(duì)秒裕,就是一臉懵逼袱蚓。
作者心聲
我也在嘗試著,能夠?qū)⑦@樣的知識(shí)分享出來(lái)几蜻,讓大家在閑暇之余能夠通過(guò)這篇文章學(xué)習(xí)到反爬蟲知識(shí)中比較簡(jiǎn)單的反爬蟲原理和實(shí)現(xiàn)方法喇潘,再熟悉他的繞過(guò)操作。比如 User-Agent 反爬手段梭稚,了解它的原理并且親手實(shí)現(xiàn)反爬蟲颖低,再親手繞過(guò)它』】荆或許通過(guò)這個(gè)小小的案例忱屑,就可以打開你思維的大門、撬開你思路的下水道暇昂。
正文
上面是空談,下面是實(shí)踐急波。一位偉人曾經(jīng)表達(dá)過(guò)這么一個(gè)意思:
管你黑貓白貓从铲,抓不到老鼠的貓,它就不是個(gè)好貓
什么是 User-Agent
User Agent中文名為用戶代理澄暮,簡(jiǎn)稱 UA名段,它是一個(gè)特殊字符串頭阱扬,使得服務(wù)器能夠識(shí)別客戶使用的操作系統(tǒng)及版本、CPU 類型伸辟、瀏覽器及版本价认、瀏覽器渲染引擎、瀏覽器語(yǔ)言自娩、瀏覽器插件等。一些網(wǎng)站常常通過(guò)判斷 UA 來(lái)給不同的操作系統(tǒng)渠退、不同的瀏覽器發(fā)送不同的頁(yè)面忙迁,因此可能造成某些頁(yè)面無(wú)法在某個(gè)瀏覽器中正常顯示,但通過(guò)偽裝 UA 可以繞過(guò)檢測(cè)碎乃。瀏覽器向服務(wù)器發(fā)起請(qǐng)求的流程圖姊扔,可以用下圖表示:
這里以火狐瀏覽器和谷歌瀏覽器為例梅誓,UA 的格式或者說(shuō)表現(xiàn)形式是這樣的:
Firefox 的 User-Agent:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:63.0) Gecko/20100101 Firefox/63.0
Chrome 的 User-Agent:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
User-Agent 在網(wǎng)絡(luò)請(qǐng)求中充當(dāng)什么角色恰梢?
在網(wǎng)絡(luò)請(qǐng)求當(dāng)中,User-Agent 是標(biāo)明身份的一種標(biāo)識(shí)梗掰,服務(wù)器可以通過(guò)請(qǐng)求頭參數(shù)中的 User-Agent 來(lái)判斷請(qǐng)求方是否是瀏覽器嵌言、客戶端程序或者其他的終端(當(dāng)然,User-Agent 的值為空也是允許的及穗,因?yàn)樗皇潜匾獏?shù))摧茴。
瀏覽器的角色埂陆,如上圖方框中所示苛白,那么 User-Agent 的角色,就是表明身份焚虱。
為什么反爬蟲會(huì)選擇 User-Agent 這個(gè)參數(shù)呢购裙?
從上面的介紹中,可以看出它是終端的身份標(biāo)識(shí)鹃栽。意味著服務(wù)器可以清楚的知道躏率,這一次的請(qǐng)求是通過(guò)火狐瀏覽器發(fā)起的,還是通過(guò) IE 瀏覽器發(fā)起的谍咆,甚至說(shuō)是否是應(yīng)用程序(比如 Python )發(fā)起的禾锤。
網(wǎng)站的頁(yè)面、動(dòng)效和圖片等內(nèi)容的呈現(xiàn)是借助于瀏覽器的渲染功能實(shí)現(xiàn)的摹察,瀏覽器是一個(gè)相對(duì)封閉的程序恩掷,因?yàn)樗_保數(shù)據(jù)的成功渲染,所以用戶無(wú)法從瀏覽器中大規(guī)模的供嚎、自動(dòng)化的獲取內(nèi)容數(shù)據(jù)黄娘。
而爬蟲卻不是這樣的峭状,爬蟲生來(lái)就是為了獲取網(wǎng)絡(luò)上的內(nèi)容并將其轉(zhuǎn)化為數(shù)據(jù)。這是兩種截然不同的方式逼争,你也可以理解為通過(guò)編寫代碼來(lái)大規(guī)模的优床、自動(dòng)化的獲取內(nèi)容數(shù)據(jù),這是一種騷操作誓焦。
回到正題,為什么會(huì)選擇 User-Agent 這個(gè)參數(shù)呢杂伟?
因?yàn)榫幊陶Z(yǔ)言都有默認(rèn)的標(biāo)識(shí)移层,在發(fā)起網(wǎng)絡(luò)請(qǐng)求的時(shí)候,這個(gè)標(biāo)識(shí)在你毫不知情的情況下赫粥,作為請(qǐng)求頭參數(shù)中的 User-Agent 值一并發(fā)送到服務(wù)器观话。比如 Python 語(yǔ)言通過(guò)代碼發(fā)起網(wǎng)絡(luò)請(qǐng)求時(shí), User-Agent 的值中就包含 Python 越平。同樣的频蛔,Java 和 PHP 這些語(yǔ)言也都有默認(rèn)的標(biāo)識(shí)。
反爬蟲的黑名單策略
既然知道編程語(yǔ)言的這個(gè)特點(diǎn)秦叛,再結(jié)合實(shí)際的需求晦溪,那么反爬蟲的思路就出來(lái)了。這是一中黑名單策略书闸,只要出現(xiàn)在黑名單中的請(qǐng)求尼变,都視為爬蟲,對(duì)于此類請(qǐng)求可以不予處理或者返回相應(yīng)的錯(cuò)誤提示浆劲。
為什么用黑名單策略不用白名單策略?
現(xiàn)實(shí)生活中牌借,瀏覽器類型繁多(火狐瀏覽器度气、谷歌瀏覽器、360 瀏覽器膨报、傲游瀏覽器磷籍、歐普拉瀏覽器、世界之窗瀏覽器现柠、QQ 瀏覽器等)院领,
想要將所有的瀏覽器品牌够吩、類型以及對(duì)應(yīng)的標(biāo)識(shí)收集并放到名單中比然,那是不實(shí)際的,假如漏掉了哪一種周循,那么對(duì)網(wǎng)站來(lái)說(shuō)是一種損失强法。
再者說(shuō)來(lái)万俗,很多的服務(wù)并不僅僅開放給瀏覽器,有些時(shí)候這些服務(wù)以 API 的形式向應(yīng)用程序提供服務(wù)饮怯,比如安卓軟件的后端 API 闰歪,為安卓軟件程序提供數(shù)據(jù)服務(wù),而軟件本身只承擔(dān)界面和結(jié)構(gòu)的任務(wù)蓖墅,而數(shù)據(jù)則從后端 API 獲取库倘。這個(gè)時(shí)候,發(fā)起的請(qǐng)求中论矾, User-Agent 就會(huì)變成 Android 于樟。
以上就是不能使用白名單策略的原因。
而黑名單在于簡(jiǎn)單拇囊,當(dāng)你希望屏蔽來(lái)自于 Python 代碼的請(qǐng)求或者來(lái)自于 Java 代碼的請(qǐng)求時(shí),只需要將其加入黑名單中即可靶橱。
通過(guò) Nginx 服務(wù)日志來(lái)查看請(qǐng)求頭中的 User-Agent
Nginx 是一款輕量級(jí)的 Web 服務(wù)器/反向代理服務(wù)器及電子郵件(IMAP/POP3)代理服務(wù)器寥袭。其特點(diǎn)是占有內(nèi)存少,并發(fā)能力強(qiáng)关霸,事實(shí)上 Nginx 的并發(fā)能力確實(shí)在同類型的網(wǎng)頁(yè)服務(wù)器中表現(xiàn)較好传黄,使用 Nginx 企業(yè)有:百度、京東队寇、新浪膘掰、網(wǎng)易、騰訊佳遣、淘寶等识埋。
Nginx 的安裝與啟動(dòng)
通沉憬ィ可以使用系統(tǒng)本身的安裝工具(Centos 的 yum窒舟、Debian 系的 apt-get 以及 MacOS 的 brew)安裝 Nginx,以 linux 系統(tǒng)為例诵盼,在終端中輸入:
sudo apt-get install nginx
接下來(lái)根據(jù)提示選擇惠豺,即可完成 Nginx 的安裝。
接著在終端通過(guò)命令:
sudo systemctl start nginx
即可啟動(dòng) Nginx 服務(wù)洁墙。
備注:由于各個(gè)系統(tǒng)差別以及版本差異,安裝和啟動(dòng)命令略有差別戒财,解決辦法自行搜索
Nginx 的日志
Nginx 為用戶提供了日志功能热监,其中記錄了每次服務(wù)器被請(qǐng)求的狀態(tài)和其他信息,包括 User-Agent固翰。 Nginx 的默認(rèn)日志存放路徑為:
/var/log/nginx/
在終端通過(guò)命令
cd /var/log/nginx && ls
可以進(jìn)入到日志存放目錄并列出目錄下的文件狼纬,可以看到其中有兩個(gè)主要的文件羹呵,為 access.log 和 error.log
它們分別記錄著成功的請(qǐng)求信息和錯(cuò)誤信息疗琉。我們通過(guò) Nginx 的訪問(wèn)日志來(lái)查看每次請(qǐng)求的信息冈欢。
發(fā)起請(qǐng)求的幾種辦法
瀏覽器
Nginx 啟動(dòng)后,默認(rèn)監(jiān)聽 80 端口盈简,你只需要訪問(wèn) IP 地址或者域名即可凑耻。假設(shè) IP 地址為 127.0.0.1,那么可以在瀏覽器輸入:
http://127.0.0.1
回車后柠贤,瀏覽器就會(huì)向服務(wù)器發(fā)起請(qǐng)求,和你平時(shí)上網(wǎng)是一樣的。
Postman
Postman是一款功能強(qiáng)大的網(wǎng)頁(yè)調(diào)試與發(fā)送網(wǎng)頁(yè)HTTP請(qǐng)求的工具(Postman下載地址)采郎,它可以模擬瀏覽器蒜埋,訪問(wèn)指定的 Url 并輸出返回內(nèi)容,實(shí)際使用如下圖所示:
Curl
這是一個(gè)利用URL語(yǔ)法在命令行下工作的傳輸工具,它不僅支持 url 地址訪問(wèn)還支持文件上傳和下載,所以可以稱它為綜合傳輸工具忆家。他也可以模擬瀏覽器卸例,訪問(wèn)指定的 Url呜舒,實(shí)際使用如下圖所示:
Nginx 日志記錄結(jié)果
上面使用了 4 種方法來(lái)向服務(wù)器發(fā)起請(qǐng)求,那么我們看看 Nginx 的日志中页响,記錄了什么樣的信息没陡。在終端通過(guò)命令:
sudo cat access.log
來(lái)查看日志文件⊥梗可以看到這幾次的請(qǐng)求記錄:
無(wú)論是 Python 還是 Curl 或者瀏覽器以及 Postman 的請(qǐng)求忽你,都被記錄在日志文件中,說(shuō)明 Nginx 可以識(shí)別發(fā)起請(qǐng)求的終端類型弹沽。
實(shí)現(xiàn)反爬蟲
之前的理論和邏輯檀夹,在實(shí)驗(yàn)中都得到了驗(yàn)證,那么接下來(lái)我們就通過(guò)黑名單策略將 Python 和 Curl 發(fā)起的請(qǐng)求過(guò)濾掉策橘,只允許 Firefox 和 Postman 的請(qǐng)求通過(guò)炸渡,并且對(duì)被過(guò)濾的請(qǐng)求返回 403 錯(cuò)誤提示。
反爬蟲的過(guò)程如上圖所示蚌堵,相當(dāng)于在服務(wù)器和資源之間建立了一道防火墻,在黑名單中的請(qǐng)求將會(huì)被當(dāng)成垃圾丟棄掉沛婴。
配置 Nginx 規(guī)則
Nginx 提供了配置文件以及對(duì)應(yīng)的規(guī)則吼畏,允許我們過(guò)濾掉不允許通過(guò)的請(qǐng)求,本次反爬蟲我們使用的就是它嘁灯。Nginx 的配置文件通常放在/etc/nginx/目錄下,名為nginx.conf泻蚊,我們通過(guò)查看配置文件來(lái)看一看,站點(diǎn)的配置文件在什么地方丑婿。再通過(guò)系統(tǒng)自帶的編輯器(筆者所用系統(tǒng)自帶 Nano性雄,其他系統(tǒng)可能自帶 Vim)來(lái)編輯配置文件。在配置文件中找到站點(diǎn)配置文件地址(筆者所用電腦存放路徑為/etc/nginx/sites-enable)羹奉,再到站點(diǎn)配置文件中找到local級(jí)別的配置秒旋,并在其中加上一下內(nèi)容:
if ($http_user_agent ~* (Python|Curl)) {
return 403;
}
這段配置的釋義是判斷請(qǐng)求中請(qǐng)求頭字符串中是否包含有 Python或者 Curl,如果包含則直接返回 403 錯(cuò)誤诀拭,否則返回正常的資源迁筛。完成配置后保存,再通過(guò)命令:
sudo nginx -s reload
整個(gè)操作過(guò)程如上圖所示细卧,讓 Nginx 服務(wù)器重新載入配置文件,使得剛才的配置生效筒占。
反爬蟲效果測(cè)試
重復(fù)上面訪問(wèn)的步驟酒甸,通過(guò)瀏覽器、Python 代碼赋铝、Postman 工具和 Curl發(fā)起請(qǐng)求插勤。從返回的結(jié)果就可以看到,與剛才是有所區(qū)別的。
- 瀏覽器返回的是正常的頁(yè)面农尖,說(shuō)明沒有收到影響析恋;
- Python 代碼的狀態(tài)碼變成了 403,而不是之前的 200
- Postman 跟之前一樣盛卡,返回了正確的內(nèi)容助隧;
- Curl 跟 Python 一樣,無(wú)法正確的訪問(wèn)資源滑沧,因?yàn)樗鼈儼l(fā)起的請(qǐng)求都被過(guò)濾掉了并村。
提示:你可以繼續(xù)修改 Nginx 的配置來(lái)進(jìn)行測(cè)試哩牍,最終會(huì)發(fā)現(xiàn)結(jié)果會(huì)跟現(xiàn)在的一樣:只要在黑名單中,請(qǐng)求就會(huì)被過(guò)濾掉并且返回 403 錯(cuò)誤令漂。
提示:這就是你平時(shí)編寫爬蟲代碼時(shí)膝昆,需要在請(qǐng)求頭中偽造瀏覽器的原因。
繞過(guò) User-Agent 方式的反爬蟲
通過(guò)上面的學(xué)習(xí)叠必,我們知道了 User-Agent 反爬蟲這種手段的原理荚孵,并且通過(guò) Nginx 來(lái)實(shí)現(xiàn)了反爬蟲,接下來(lái)我們一起學(xué)習(xí)如何繞過(guò)這種反爬蟲措施纬朝。
Python 繞過(guò)反爬蟲
在 Requests 庫(kù)中收叶,允許用戶自定義請(qǐng)求頭信息,所以我們可以在請(qǐng)求頭信息中將 User-Agent 的值改為瀏覽器的請(qǐng)求頭標(biāo)識(shí)共苛,這樣就能夠欺騙 Nginx 服務(wù)器判没,達(dá)到繞過(guò)反爬蟲的目的。將之前的 Python 代碼改為:
代碼中我們用到的是 Firefox 瀏覽器的請(qǐng)求頭信息,而且為了更好的觀察效果绕德,我們可以更改瀏覽器的版本號(hào)(改成9527)以區(qū)分真實(shí)瀏覽器(這不會(huì)影響請(qǐng)求結(jié)果)患膛。運(yùn)行這個(gè)文件,看看得到的返回結(jié)果:
200
不是 403 了耻蛇,說(shuō)明已經(jīng)繞過(guò)了這種類型的反爬蟲(你看踪蹬,這就是網(wǎng)上那些文章所寫的,需要修改請(qǐng)求頭信息才能繞過(guò)反爬蟲臣咖,現(xiàn)在你明白是怎么回事了吧)跃捣。
練習(xí):使用 Postman 再測(cè)試一下
一個(gè)測(cè)試也許不準(zhǔn)確,你還可以通過(guò) Postman 再來(lái)測(cè)試一下夺蛇,還記得怎么做嗎疚漆?
- 將需要過(guò)濾的標(biāo)識(shí)(Postman)添加到 Nginx 的配置文件中
- 重載配置文件,使其生效
- 通過(guò) Postman 發(fā)起請(qǐng)求看看是否會(huì)被過(guò)濾
- 再次使用 Postman 工具,并且攜帶上瀏覽器的標(biāo)識(shí)再發(fā)起請(qǐng)求娶聘,看看是否會(huì)被過(guò)濾
小提示:這個(gè)練習(xí)如果你自己來(lái)做的話闻镶,會(huì)更容易理解其中的原理,并且可以加深你的映像丸升。
總結(jié)
回顧一下铆农,整篇文章的過(guò)程:
我們從遇到的反爬蟲現(xiàn)象開始入手狡耻,接著學(xué)習(xí)了 User-Agent 這種反爬蟲策略的原理墩剖,并且通過(guò) Nginx 實(shí)現(xiàn)了反爬蟲,最后通過(guò) Python 代碼示例和 Postman 示例來(lái)驗(yàn)證我們的想法夷狰,最終清清楚楚岭皂、明明白白的了解到其中的緣由,待目標(biāo)改變了它的策略時(shí)孵淘,我們也可以清楚的知道可以使用哪些方法來(lái)繞過(guò)蒲障。
作者:韋世東、 轉(zhuǎn)自:進(jìn)擊的Coder