1. 程式人生 > >爬蟲還不夠?那再學學反爬!

爬蟲還不夠?那再學學反爬!

爬蟲與反爬蟲,這相愛相殺的一對,在現在你會爬蟲是不夠的,你還得會反爬蟲。

為 Python 平反

首先是爬蟲,爬蟲教程你到處都可以搜的到,大部分是 Python 寫的。

我曾經在一篇文章提到過:用 Python 寫的爬蟲是最薄弱的,因為天生並不適合破解反爬蟲邏輯,因為反爬蟲都是用 JavaScript 來處理。

然而慢慢的,我發現這個理解有點問題(當然我如果說我當時是出於工作需要而有意黑 Python,你們信嗎。。。)。

Python 的確不適合寫反爬蟲邏輯,但是 Python 是一門膠水語言,他適合捆綁任何一種框架。

而反爬蟲策略經常會變化的翻天覆地,需要對程式碼進行大刀闊斧的重構,甚至重寫。這種情況下,Python 不失為一種合適的解決方案。

舉個例子,你之前是用 selenium 爬取對方的站點,後來你發現自己被封了,而且封鎖方式十分隱蔽,完全搞不清到底是如何封的,你會怎麼辦?你會跟蹤 selenium 的原始碼來找到出錯的地方嗎?

你不會,你只會換個框架,用另一種方式來爬取,然後你就把兩個框架都淺嘗輒止地用了下,一個都沒有深入研究過。

因為沒等你研究好,也許人家又換方式了,你不得不再找個框架來爬取。畢竟,老闆等著明天早上開會要資料呢。

老闆一般都是早上八九點開會,所以你七點之前必須搞定。等你厭倦了,打算換個工作的時候,簡歷上又只能寫“瞭解 n 個框架的使用”,僅此而已。

這就是爬蟲工程師的宿命,爬蟲工程師比外包還可憐。外包雖然不容易積累技術,但是好歹有正常上下班時間,爬蟲工程師連這個權利都沒有。

然而反爬蟲工程師就不可憐了嗎?也不是的,反爬蟲有個天生的死穴,就是:誤傷率。

爬蟲與反爬蟲,是一個很不陽光的行業。這裡說的不陽光,有兩個含義。

第一是,這個行業是隱藏在地下的,一般很少被曝光出來。很多公司對外都不會宣稱自己有爬蟲團隊,甚至隱瞞自己有反爬蟲團隊的事實。這可能是出於公司戰略角度來看的,與技術無關。

第二是,這個行業並不是一個很積極向上的行業。很多人在這個行業摸爬滾打了多年,積攢了大量的經驗,但是悲哀的發現,這些經驗很難兌換成閃光的簡歷。

面試的時候,因為雙方爬蟲理念或者反爬蟲理念不同,也很可能互不認可,影響自己的求職之路。本來程式設計師就有“文人相輕”的傾向,何況理念真的大不同。

然而這就是程式設計師的宿命。不管這個行業有多麼的不陽光,依然無法阻擋大量的人進入這個行業,因為有公司的需求。

那麼,公司到底有什麼樣的需求,導致了我們真的需要爬蟲/反爬蟲呢?

反爬蟲很好理解,有了爬蟲我們自然要反爬蟲。對於程式設計師來說,哪怕僅僅是出於“我就是要證明我技術比你好”的目的,也會去做。

對於公司來說,意義更加重大,最少,也能降低伺服器負載,光憑這一點,反爬蟲就有充足的生存價值。

那麼爬蟲呢?最早的爬蟲起源於搜尋引擎。搜尋引擎是善意的爬蟲,可以檢索你的一切資訊,並提供給其他使用者訪問。為此他們還專門定義了 robots.txt 檔案,作為君子協定,這是一個雙贏的局面。

然而事情很快被一些人破壞了,爬蟲很快就變的不再“君子”了。後來有了“大資料”,無數的媒體鼓吹大資料是未來的趨勢,吸引了一批又一批的炮灰去創辦大資料公司。

這些人手頭根本沒有大資料,他們的資料只要用一個 U 盤就可以裝的下,怎麼好意思叫大資料呢?

這麼點資料根本忽悠不了投資者,於是他們開始寫爬蟲,拼命地爬取各個公司的資料。很快他們的資料,就無法用一個 U 盤裝下了。這個時候終於可以休息休息,然後出去吹噓融資啦。

然而可悲的是,大容量 U 盤不斷地在釋出,他們總是在拼命地追趕儲存增加的速度。

爬蟲與反爬蟲

爬蟲反爬蟲執行現狀

電子商務行業的爬蟲與反爬蟲更有趣一些,最初的爬蟲需求來源於比價。

這是某些電商網站的核心業務,大家買商品的時候,是一個價格敏感型使用者的話,很可能用過網上的比價功能(真心很好用啊)。

毫無懸念,他們會使用爬蟲技術來爬取所有相關電商的價格。他們的爬蟲還是比較溫柔的,對大家的伺服器不會造成太大的壓力。

然而,這並不意味著大家喜歡被他爬取,畢竟這對其他電商是不利的,於是需要通過技術手段來做反爬蟲。

按照技術人員的想法,對方用技術懟過來,我們就要用技術懟回去,不能慫啊。這個想法是很好的,但是實際應用起來根本不是這麼回事。

誠然,技術是很重要的,但是實際操作上,更重要的是套路。誰的套路更深,誰就能玩弄對方於鼓掌之中。

誰的套路不行,有再好的技術,也只能被耍的團團轉。這個雖然有點傷技術人員的自尊,然而,我們也不是第一天被傷自尊了。大家應該早就習慣了吧。

真實世界的爬蟲比例

大家應該聽過一句話吧,大概意思是說,整個網際網路上大概有 50% 以上的流量其實是爬蟲。

第一次聽這句話的時候,我還不是很相信,我覺得這個說法實在是太誇張了。怎麼可能爬蟲比人還多呢? 爬蟲畢竟只是個輔助而已。

現在做了這麼久的反爬蟲,我依然覺得這句話太誇張了。50%?你在逗我?就這麼少的量?

舉個例子,某公司,某個頁面的介面,每分鐘訪問量是 1.2 萬左右,這裡面有多少是正常使用者呢?50%?60%?還是?

正確答案是:500 以下。也就是說,一個單獨的頁面,12000 的訪問量裡,有 500 是正常使用者,其餘是爬蟲。

注意,統計爬蟲的時候,考慮到你不可能識別出所有的爬蟲,因此,這 500 個使用者裡面,其實還隱藏著一些爬蟲。

那麼爬蟲率大概是:(12000-500)/12000=95.8%。

這個數字你猜到了嗎?這麼大的爬蟲量,這麼少的使用者量,大家到底是在幹什麼?是什麼原因導致了明明是百人級別的生意,卻需要萬級別的爬蟲來做輔助? 95% 以上,19 保 1?

答案可能會相當令人噴飯,這些爬蟲大部分是由於決策失誤導致的。

哭笑不得的決策思路

舉個例子,這個世界存在 3 家公司,售賣相同的電商產品,三家公司的名字分別是 A,B,C。

這個時候,客戶去 A 公司查詢了下某商品的價格,看了下發現價格不好,於是他不打算買了,他對整個行業的訂單貢獻為 0。

然而 A 公司的後臺會檢測到,我們有個客戶流失了,原因是他來查詢了一個商品,這個商品我們的價格不好,沒關係,我去爬爬別人試試。

於是他分別爬取了 B 公司和 C 公司,B 公司的後臺檢測到有人來查詢價格,但是呢,最終沒有下單。

他會認為,嗯,我們流失了一個客戶。怎麼辦呢?我可以爬爬看,別人什麼價格。

於是他爬取了 A 和 C,C 公司的後臺檢測到有人來查詢價格。。。。。

過了一段時間,三家公司的伺服器分別報警,訪問量過高。三家公司的 CTO 也很納悶,沒有生成任何訂單啊,怎麼訪問量這麼高?

一定是其他兩家禽獸寫的爬蟲沒有限制好頻率。媽的,老子要報仇!於是分別做反爬蟲,不讓對方抓自己的資料。

然後進一步強化自己的爬蟲團隊抓別人的資料。一定要做到:寧叫我抓天下人,休叫天下人抓我。

然後,做反爬蟲的就要加班天天研究如何攔截爬蟲,做爬蟲的被攔截了,就要天天研究如何破解反爬蟲策略。

大家就這麼把資源全都浪費在沒用的地方了,直到大家合併了,才會心平氣和的坐下來談談,都少抓點。

最近國內的公司有大量的合併,我猜這種“心平氣和”應該不少吧?

爬蟲反爬蟲技術現狀

下面我們談談,爬蟲和反爬蟲分別都是怎麼做的。有需要一起學習,交流的小夥伴可以進群:425851955,需要學習資料也可以找我。

無法繞開的誤傷率

我們首先談談,面對對方的爬蟲,你的第一反應是什麼?

如果限定時間的話,大部分人給我的答案都是:封殺對方的 IP。

然而,問題就出在,IP 不是每人一個的,大的公司有出口 IP,ISP 有的時候會劫持流量讓你們走代理,有的人天生喜歡掛代理,有的人為了翻牆 24 小時掛 VPN。

最坑的是,現在是移動網際網路時代,你如果封了一個 IP?不好意思,這是中國聯通的 4G 網路,5 分鐘之前還是別人,5 分鐘之後就換人了哦!

因此,封 IP 的誤傷指數最高,並且,效果又是最差的,因為現在即使是最菜的新手,也知道用代理池了。

你們可以去淘寶看下,幾十萬的代理價值多少錢?我們就不談到處都有的免費代理了。

也有人說:我可以掃描對方埠,如果開放了代理埠,那就意味著是個代理,我就可以封殺了呀。

事實是殘酷的,我曾經封殺過一個 IP,因為他開放了一個代理埠,而且是個很小眾的代理埠。

不出一天就有人來報事件,說我們一個分公司被攔截了,我一查 IP,還真是我封的 IP。

我就很鬱悶地問他們 IT,開這個端口乾什麼?他說做郵件伺服器啊。我說為啥要用這麼奇怪的埠?他說,這不是怕別人猜出來麼?我就隨便取了個。

掃描埠的進階版,還有一種方式,就是去訂單庫查詢這個 IP 是否下過訂單,如果沒有,那麼就是安全的;如果有,那就不安全,有很多網站會使用這個方法。

然而這只是一種自欺欺人的辦法而已,只需要下一單,就可以永久洗白自己的 IP,天下還有比這更便宜的生意嗎?

因此,封 IP,以及封 IP 的進階版:掃描埠再封 IP,都是沒用的。根本不要考慮從 IP 下手,因為對手會用大量的時間考慮如何躲避 IP 封鎖,你幹嘛和人家硬碰呢?這沒有任何意義。

那麼,下一步你會考慮到什麼?很多站點的工程師會考慮:既然沒辦法阻止對方,那我就讓它變的不可讀吧。我會用圖片來渲染關鍵資訊,比如價格。這樣,人眼可見,機器識別不出來。

這個想法曾經是正確的,然而,坑爹的技術發展,帶給我們一個坑爹的技術,叫機器學習。順便帶動了一個行業的迅猛發展,叫 OCR。

很快,識別影象就不再是任何難題了,甚至連人眼都很難識別的驗證碼,有的 OCR 都能搞定,比我肉眼識別率都高。更何況,現在有了打碼平臺,用資本都可以搞定,都不需要技術。

那麼,下一步你會考慮什麼?這個時候,後端工程師已經沒有太多的辦法可以搞了。

不過後端搞不定的事情,一般都推給前端啊,前端從來都是後端搞不定問題時的背鍋俠。

多少年來我們都是這麼過來的,前端工程師這個時候就要勇敢地站出來了:“都不要得瑟了,來比比誰的前端知識牛逼,你牛逼我就讓你爬。”

我不知道這篇文章的讀者裡有多少前端工程師,我只是想順便提一下:你們以後將會是更加搶手的人才。

前端工程師的逆襲

我們知道,一個數據要顯示到前端,不僅僅是後端輸出就完事了,前端要做大量的事情,比如取到 json 之後,至少要用 template 轉成 html 吧?

這已經是步驟最少最簡單的了,然後你總要用 css 渲染下吧? 這也不是什麼難事。

等等,你還記得自己第一次做這個事情的時候的經歷嗎?真的,不是什麼難事嗎?

有沒有經歷過,一個 html 標籤拼錯,或者沒有閉合,導致頁面錯亂?一個 css 沒弄好,導致整個頁面都不知道飄到哪去了?

這些事情,你是不是很想讓別人再經歷一次?

這件事情充分說明了:讓一個資深的前端工程師來把事情搞複雜一點,對方如果配備了資深前端工程師來破解,也需要耗費 3 倍以上的時間。

畢竟是讀別人的程式碼,別人寫程式碼用了一分鐘,你總是要讀兩分鐘,然後罵一分鐘吧?這已經算很少的了。如果對方沒有配備前端工程師。。。那麼經過一段時間,他們會成長為前端工程師。

之後,由於前端工程師的待遇比爬蟲工程師稍好一些,他們很快會離職做前端,既緩解了前端人才缺口,又可以讓對方缺人,重招。

而他們一般是招後端做爬蟲,這些人需要再接受一次折磨,再次成長為前端工程師,這不是很好的事情嗎?

所以,如果你手下的爬蟲工程師離職率很高,請仔細思考下,是不是自己的招聘方向有問題。

那麼前端最坑爹的技術是什麼呢?前端最坑爹的,也是最強大的,就是我們的:JavaScript。

JavaScript 有大量的花樣可以玩,毫不誇張的說,一週換一個 feature(Bug)給對方學習,一年不帶重樣的。這個時候你就相當於一個面試官,對方要通過你的面試才行。

舉個例子,在 Array.prototyp e裡,有沒有 map 啊?什麼時候有啊?你說你是 xx 瀏覽器,那你這個應該是有還是應該沒有啊?你說這個可以有啊?可是這個真沒有啊。

那[]能不能在 string 裡面獲取字元啊?哪個瀏覽器可以哪個不行啊?咦!你為什麼支援 WebKit 字首啊?等等,剛剛你還支援怎麼現在不支援了啊?你宣告的不對啊。

這些對於前端都是簡單的知識,已經習以為常了,但是對於後端來說簡直就是噩夢。

然而,前端人員自己作死,研究出了一個東西,叫:Nodejs。基於 V8,秒殺所有的 js 執行。

不過 Nodejs 實現了大量的 feature,都是瀏覽器不存在的,你隨隨便便訪問一些東西(比如你為什麼會支援 process.exit),都會把 node 坑的好慘好慘。

而且瀏覽器裡的 js,你拉到後臺用 Nodejs 跑,你是不是想到了什麼安全漏洞?這個是不是叫,程式碼與資料混合?如果他在 js 裡跑點噁心的程式碼,瀏覽器不支援但是 node 支援怎麼辦?

還好,爬蟲工程師還有 phantomjs。但是,你怎麼沒有定位啊? 哈哈,你終於模擬出了定位。

但是不對啊,根據我當前設定的安全策略你現在不應該能定位啊?你是怎麼定出來的?連 phantomjs 的作者自己都維護不下去了,你真的願意繼續用嗎?

當然了,最終,所有的反爬蟲策略都逃不脫被破解的命運。但是這需要時間,反爬蟲需要做的就是頻繁釋出,拖垮對方。

如果對方兩天可以破解你的系統,你就一天一發布,那麼你就是安全的。這個系統甚至可以改名叫做“每天一道反爬題,輕輕鬆鬆學前端”。

誤傷,還是誤傷

這又回到了我們開始提到的“誤傷率”的問題了。我們知道,釋出越頻繁,出問題的概率越高。那麼,如何在頻繁釋出的情況下,還能做到少出問題呢?

此外還有一個問題,我們寫了大量的“不可讀程式碼”給對方,的確能給對方造成大量的壓力,但是,這些程式碼我們自己也要維護啊。

如果有一天忽然說,沒人爬我們了,你們把程式碼下線掉吧。這個時候寫程式碼的人已經不在了,你們怎麼知道如何下線這些程式碼呢?

這兩個問題我暫時不能公佈我們的做法,但是大家都是聰明人,應該都是有自己的方案的,軟體行業之所以忙的不得了,無非就是在折騰兩件事,一個是如何將程式碼拆分開,一個是如何將程式碼合併起來。

關於誤傷率,我只提一個小的 tip:你可以只開啟反爬蟲,但是不攔截,先放著,發統計資訊給自己,相當於模擬演練。

等統計的差不多了,發現真的開啟了也不會有什麼問題,那就開啟攔截或者開啟造假。

這裡就引發了一個問題,往往一個公司的各個頻道,爬取難度是不一樣的。原因就是,誤傷檢測這種東西與業務相關,公司的基礎部門很難做出通用的,只能各個部門自己做,甚至有的部門做了有的沒做。

因此引發了爬蟲界一個奇葩的通用做法:如果 PC 頁面爬不到,就去 H5 試試,如果 H5 很麻煩,就去 PC 碰碰運氣。

爬蟲反爬蟲套路現狀

那麼一旦有發現對方資料造假怎麼辦?

早期的時候,大家都是要抽查資料,通過資料來檢測對方是否有造假,這個需要人工核對,成本非常高。

可是那已經是洪荒時代的事情了。如果你們公司還在通過這種方式來檢測,說明你們的技術還比較落伍。

之前我們的競爭對手是這麼幹的:他們會抓取我們兩次,一次是他們解密出來 key 之後,用正經方式來抓取,這次的結果定為 A。

一次是不帶 key,直接來抓,這次的結果定為 B。根據前文描述,我們可以知道,B 一定是錯誤的。那麼如果 A 與 B 相等,說明自己中招了,這個時候會停掉爬蟲,重新破解。

不要回應

所以之前有一篇關於爬蟲的文章,說如何破解我們的。一直有人要我回復下,我一直覺得沒什麼可以回覆的。

第一,反爬蟲被破解了是正常的。這個世界上有個萬能的爬蟲手段,叫“人肉爬蟲”。

假設我們就是有錢,在印度開個分公司,每天僱便宜的勞動力用滑鼠直接來點,你能拿我怎麼辦?

第二,我們真正關心的是後續的這些套路。而我讀了那篇文章,發現只是呼叫了selenium並且拿到了結果,就認為自己成功了。

我相信你讀到這裡,應該已經明白為什麼我不願意回覆了。我們最重要的是工作,而不是誰打誰的臉。

大家如果經常混技術社群就會發現,每天熱衷於打別人臉的,一般技術都不是很好。

當然這並不代表我們技術天下第一什麼的,我們每天面對大量的爬蟲,還是遇到過很多高手的。

就如同武俠小說裡一樣,高手一般都比較低調,他們默默地拿走資料,很難被發現,而且頻率極低,不會影響我們的考評。你們應該明白,這是智商與情商兼具的高手了。

我們還碰到拉走我們 js,砍掉無用的部分直接解出 key,相當高效不拖泥帶水的爬蟲,一點廢請求都沒有(相比某些爬蟲教程,總是教你多訪問,寫沒用的 url 免得被發現,真的不知道高到哪裡去了。這樣做除了會導致機器報警,導致對方加班封鎖以外,對你自己沒有任何好處)。

而我們能發現這一點僅僅是是因為他低調地寫了一篇部落格,通篇只介紹技術,沒有提任何沒用的東西。

這裡我只是順便發了點小牢騷,就是希望後續不要總是有人讓我回應一些關於爬蟲的文章。

線下我認識很多爬蟲工程師,水平真的很好,也真的很低調(不然你以為我是怎麼知道如何對付爬蟲的。。。),大家都是一起混的,不會產生“一定要互相打臉”的情緒。

進化

早期我們和競爭對手打的時候,雙方的技術都比較初級。後來慢慢的,爬蟲在升級,反爬蟲也在升級,這個我們稱為“進化”。

我們曾經給對方放過水,來試圖拖慢他們的進化速度,然而,效果不是特別理想。爬蟲是否進化,取決於爬蟲工程師自己的 KPI,而不是反爬蟲的進化速度。

後期打到白熱化的時候,用的技術越來越匪夷所思。舉個例子,很多人會提,做反爬蟲會用到 canvas 指紋,並認為是最高境界。

其實這個對於反爬蟲來說也只是個輔助,canvas 指紋的含義是,因為不同硬體對 canvas 支援不同,因此你只要畫一個很複雜的 canvas,那麼得出的 image,總是存在畫素級別的誤差。

考慮到爬蟲程式碼都是統一的,就算起 selenium,也是 Ghost 的,因此指紋一般都是一致的,因此繞過幾率非常低。

但是!這個東西天生有兩個缺陷。

第一是,無法驗證合法性。當然了,你可以用非對稱加密來保證合法,但是這個並不靠譜。

其次,canvas 的衝突概率非常高,遠遠不是作者宣稱的那樣,衝突率極低。也許在國外衝突是比較低,因為國外的語言比較多。但是國內公司通常是 IT 統一裝機,無論是軟體還是硬體都驚人的一致。

我們測試 canvas 指紋的時候,在攜程內部隨便找了 20 多臺機器,得出的指紋都完全一樣,一丁點差別都沒有。因此,有些“高階技巧”一點都不實用。

法律途徑

此外就是大家可能都考慮過的:爬蟲違法嗎?能起訴對方讓對方不爬嗎?法務給的答案到是很乾脆,可以,前提是證據。

遺憾的是,這個世界上大部分的爬蟲爬取資料是不會公佈到自己網站的,只是用於自己的資料分析。

因此,即使有一些關於爬蟲的官司做為先例,並且已經打完了,依然對我們沒有任何幫助。反爬蟲,在對方足夠低調的情況下,註定還是個技術活。

搞事情,立 Flag

到了後來,我們已經不再侷限於打打技術了,反爬蟲的程式碼裡我們經常埋點小彩蛋給對方,比如寫點註釋給對方。雙方通過互相交戰,頻繁釋出,居然聊的挺 high 的。

比如問問對方,北京房價是不是很高啊?對方迴應,歐巴,我可是憑本事吃飯哦。繼續問,搖到號了嗎?諸如此類等等。

這樣的事情你來我往的,很容易動搖對方的軍心,還是很有作用的。試想一下,如果你的爬蟲工程師在大年三十還苦逼加班的時候,看到對方留言說自己拿到了 n 個月的年終獎,你覺得你的工程師,離辭職還遠嗎?

最後,我們終於搞出了大動作,覺得一定可以坑對方很久了。我們還特意去一家小火鍋店吃了一頓,慶祝一下,準備明天上線。

大家都知道,一般立 Flag 的下場都比較慘的,兩個小時的自助火鍋,我們剛吃五分鐘,就得到了我們投資競爭對手的訊息。

後面的一個多小時,團隊氣氛都很尷尬,誰也說不出什麼話。我們組有個實習生,後來鼓足勇氣問了我一個問題:“我還能留下來嗎?”

畢竟,大部分情況下,技術還是要屈服於資本的力量。

爬蟲反爬蟲的未來

與競爭對手和解之後,我們去拜訪對方,大家坐在了一起。之前網上自稱妹子的,一個個都是五大三粗的漢子,這讓我們相當絕望。

在場唯一的一個妹子還是我們自己帶過去的(就是上面提到的實習生),感覺套路了這麼久,最終還是被對方套路了。

好在,吃的喝的都很好,大家玩的還是比較 high 的。後續就是和平年代啦,大家不打仗了,反爬蟲的邏輯扔在那做個防禦,然後就開放白名單允許對方爬取了。

群裡經常叫的就是:xxx 你怎麼頻率這麼高,xxx 你為什麼這個介面沒給我開放,為什麼我爬的東西不對我靠你是不是把我封了啊,諸如此類的。

和平年代的反爬蟲比戰爭年代還難做,因為戰爭年代,誤傷率只要不是太高,公司就可以接受。

和平年代大家不能搞事情,誤傷率稍稍多一點,就會有人叫:好好的不賺錢,瞎搞什麼搞。

此外,戰爭年代只要不攔截使用者,就不算誤傷。和平年代還要考慮白名單,攔截了合作伙伴也是誤傷,因此各方面會更保守一些。

不過,總體來說還是和平年代比較 happy,畢竟,誰會喜歡沒事加班玩呢。

然而和平持續的不是很久,很快就有了新的競爭對手選擇爬蟲來與我們打,畢竟,這是一個利益驅使的世界。

只要有大量的利潤,資本家就會殺人放火,這不是我們這些技術人員可以決定的,我們希望天下無蟲,但是我們又有什麼權利呢。

好在,這樣可以催生更多的職位,順便提高大家的身價,也算是個好事情吧。