序言
這篇文章沒有程式碼,請放心閱讀。
多年以後,面對人工智慧研究員那混亂不堪的程式碼,我會想起第一次和 S 君相見的那個遙遠的下午。那時的 B 公司,還是一個僅有 6 個人的小團隊,Mac 和顯示器在桌上依次排開,大家坐在一起,不需要稱呼姓名,轉過臉去,對方就知道你在和他說話。一切看起來都那麼美好,我們所有人,都希望自己和這個公司能夠一起成長。
彼時 S 君剛從加拿大回來,老闆把他介紹給我們,於是 S 君作為資料產品經理跟我有了專案上的接觸。
創業公司裡面,每一個人都需要會很多的技藝,於是 S 君開始自學 Python。
有一天,S 君問我:“你玩 MineCraft(我的世界) 嗎?“
“玩,但我更喜歡在 B 站上看別人的世界。”我答道。
“我覺得我現在寫程式,像是在玩‘我的世界’。”S 君笑著說道。
“是不是覺得你已經掌握了 Python 的基本語法,看著別人把 Python 用的溜溜轉,而你自己卻不知道用它來做什麼?”
“是這樣的,你懂我。”
“那你學一門雜學吧。”
於是 S 君被我誘拐過來跟我一起寫爬蟲。
後來,S 君離開了 B 公司。
三個月後,我也離開了。
從此,我們再也沒有見過。
程式設計最重要的能力是變通
S 君是一個老實孩子。
在開發一個爬蟲的過程中,網站介面傳回給他的資料看起來是 JSON 格式,於是他就用 Python 自帶的 JSON 庫去解析。結果解析失敗了。因為這些所謂的看起來像 JSON 的東西,竟然沒有雙引號。
難道是 JSON 的超集?S 君一通搜尋,發現用 YMAL 庫也許可以解析這種資料。於是安裝 YMAL 庫,一解析又報錯。
難道這些資料直接就是 Python 的字典?於是 S 君用上了邪惡的 eval。又報錯,因為裡面有 null 和小寫的 true。
“你為什麼不試一試直接用正則運算式呢?”我對S君說。
“靠!”S 君一拍桌子,旁邊的老闆嚇得把搪瓷杯子裡面的快樂水灑在了白襯衣上。
然後 S 君用正則運算式花了 10 秒鐘結束了戰鬥。
寫爬蟲與三峽大壩
有一天,S 君興衝衝地跑來跟我說:“我體會到三峽大壩的偉大功能了!”
“你是爬蟲工程師還是水利工程師?”
“你知道嗎,不管上游的水勢多麼兇猛,從大壩出來以後總是安全而穩定。”S 君並沒有回答我的問題,而是自顧自地說道。
“原來你開始用 Kafka 了。不錯,孺子可教。”
S 君吐了一下舌頭:“還是師傅教導有方。”
前不久,S 君的爬蟲剛剛達到了日產資料千萬條的標的。然而他只高興了一天。因為他發現,資料寫到資料庫以後,讀起來很麻煩。
S 君有多個資料分析的系統需要從資料庫裡面讀取爬蟲爬好的資料,但是從每天千萬量級的資料中尋找特定的資料是一個很慢的過程。如果程式遇到異常導致崩潰,又得從頭開始讀。
S 君問我:“現在我每一個資料分析的指令碼都要從資料庫裡面讀一次資料,做了太多重覆的工作,單機單節點的資料庫快要撐不住了。我是不是要去學習分庫分表搭建叢集啊?”
我告訴 S 君:“這個後面你自然是需要去做的。但現在,你可以先試一試 Kafka,我已經搭建好了一個 Kafka 的叢集了,你這樣使用……”。
後來,S 君讓所有爬蟲把爬到的資料到直接送進了 Kafka,然後再從 Kafka 裡面讀資料出來,一個 Group 用來備份原始資料,一份 Group 用來生成中間表,一份 Group 用來監控報警,一份 Group 用來繪製 DashBoard。無論爬蟲塞給 Kafka 的資料有多少,有多快,從 Kafka 讀資料的地方都能按照自己的節奏來消費和使用。
既然收集了資料就要讓它發光發熱
S 君在加拿大留學時學的專業是金融數學和統計。所以他對資料分析也很有興趣。在他爬蟲收集的資料夠用以後,我跟他講瞭如何使用 Pandas 來分析資料。
S 君把他分析的酒店價格變化資料給分享給了我們。不愧是金融+數學+統計學背景的高階知識分子 + 超級強大的 Pandas + 超級好用的 Jupyter。這份資料不僅完美再現了過去一年的價格走勢,還預測了未來的任何變化,多達四十六張圖表似乎窮盡了所有的組合。
草木竹石皆可破敵
S 君曾經遇到過一個特別簡單的電商網站。頁面幾乎畫素級抄襲淘寶,但是完全沒有任何反爬蟲的機制。以 S 君的水平,從審查元素,到開發完成,僅僅用了半個小時。爬蟲安全平穩又順利地運行了三個星期。
然後,有一天早上,爬蟲死掉了。
S 君用盡畢生所學,無法再從這個網站上爬到任何有價值的資訊。這個網站似乎請來了一個機器行為對抗的大神級人物。人用瀏覽器一點問題都沒有,但 S 君的任何隱藏爬蟲的手段都被輕易識破。
S 君找到我:“師傅,這個網站我搞不定。”
“你能搞定。動動腦子。”
“我會的所有技術都用上了,完全看不出破解他反爬蟲機制的方法。”S 君已經失去了信心。
“那就,不要用技術去對抗。用你的腦子。”
S 君抱著顯示器用頭一遍一遍的撞。
我問 S 君:“你有沒有思考一個問題,這個網站模仿了淘寶的皮,卻又毫無反爬蟲機制。你覺得他的老闆是一個什麼樣的人?你聽過那個段子嗎?”
S 君突然一躍而起:“我給你一萬元,你幫我做一個網站吧。你想要什麼樣的網站?很簡單,就淘寶那樣的。你是說這個段子嗎?”
“對。”
S 君突然之間榮光煥發:“有辦法了!”
只見 S 君重新在瀏覽器開啟了這個網站,找到了客戶服務熱線。電話一撥通他就開始一通汙言穢語罵起來:“……你們網站到底在搞什麼?為什麼今天一會能登入一會不能登入?找你們老闆來!我來教他怎麼做網站!……”
半小時以後,網站反爬蟲機制全部解除。
此刻,S 君面向西面雙手合十,自言自語:“兄弟,對不起了,只有讓你來背這個鍋了。”
你小學上課傳過紙條嗎
“我現在能體會那些半路攔截紙條的人是什麼心態了。”這是 S 君第一次使用 Charles 時對我說的話。
從此以後,我很少看到 S 君分析網頁了。因為他學會了在爬蟲開發的過程中,首先透過中間人攻擊技術分析微信小程式和手機 App。這種方式往往能夠直接獲得資料,拿到資料以後就能直接儲存,再也不用寫煩人的 XPath 或者長的跟表情符號一樣的正則運算式了。
有一天,我在玩一個網頁版的駭客解密遊戲,在網頁上尋找某個地方隱藏起來的密碼,然後輸入每一關的回答框中,答對才能進入下一關。
遊戲有 12 關,而我卡在了第 6 關。只見 S 君拿著電腦走到我面前,指著第 12 關的通關頁面跟我炫耀。
“你是不是用 MITMProxy 替換了這個網站的 Js 檔案?”
“果然還是瞞不過師傅你啊。”
“你攔截了別人的紙條,做了修改,然後又疊好繼續傳下去,你有考慮過發紙條的人和收紙條的人的感受嗎?”
“我小學時候不傳紙條,都是妹子直接約我的。”
加密?不存在的
“前端沒有秘密”。S 君在成功逆向了一個網站的 Js 檔案以後如是對我說。
“那是因為這個網站的 Js 程式碼就赤裸裸地放在你面前,完全沒有混淆。”我對 S 君說道。
“不怕,我可以用 Node.js 來執行混淆過的程式碼。我已經搭建好 Node.js 服務了,只要把 Js 程式碼傳進去,他就會把結果給我傳回回來。”S 君對此似乎一臉自行。
“你什麼時候學會的 Node.js?”
“這不是師傅你說過技多不壓身嗎?既然做爬蟲需要動 JavaScript,那我順手就把 Node.js 給學了。”S 君毫不畏懼的表情,似乎證明他已經猜透了我要問什麼。
“那如果標的沒有網站,只有 App 呢?”
“不怕,Android 逆向工程我也順便研究了一點。Java 我也看得懂。”
“看來這些已經不需要我再教你了。”
我一根指頭就能捏死你,但我不想傷害你
S 君有一天問我:“假設你現在在小學課堂上,前面的同學讓你把紙條傳給後面的女生,你會怎麼做?”
我說:“檢視複製/修改刪除/攔截丟棄”。
S 君嘿嘿一笑:“比如說,前後三次的紙條分別為‘聽說你奶奶生病了,我們週末一起去看望她吧‘,’今晚我爸媽不在,去我家玩嗎?’, ‘我剛拿到這個月壓歲錢,老師一下課我們就去吃好吃的。’”
我說:“女孩漂亮的話,我改一下第二張紙條,改成‘今晚我爸媽不在,我們一起去青南家玩嗎?’”。
S 君露出了嫌棄的眼神:“師傅,你可是說過你最討厭技術含量低的事情啊,你塗改了紙條,別人不會發現?你筆跡都不一樣啊!”。
我問 S 君:“那你有何高見?”
S君抬頭仰望這窗外的天空:“如果是我,那麼我會臨摹第一張紙條上面的‘生病了’、‘去’、‘看望’、‘她’、‘我’,第二張紙條上面的‘爸媽’,第三張紙條上面的‘拿’、‘錢’、‘老師’這些字的筆跡。然後改換一下順序就變成了:‘爸媽,我老師生病了,我拿錢去看望她’。最後我把這張偽造的紙條拿去找寫紙條的那個同學他爸媽要錢。”
“我猜,你想用中間人攻擊擷取別人的 Cookies,然後用這些 Cookies 偷偷登入網站,進行你的不可告人的目的。”
S 君笑道:“哈哈哈,我想想都害怕。但是每當我想到,我擁有一種可怕的力量,而我還能控制住這種力量。我就知道我和街上的普通人不一樣了。”
你肯定薅了直播答題的羊毛吧
去年年底的直播答題著實火了一把。那個時候,我和 S 君分開已經有一段時間了。我相信,在全民答題的每一個夜晚,S 君的電腦上一定連著不少於六臺安卓手機。這些手機執行著不同的答題平臺,能夠自動讀取螢幕上的問題並自動選擇答案。
我把安卓自動化測試技術教給 S 君,本來是讓他結合爬蟲,實現群控從而抓取一些難以處理的資料,但我相信他肯定會用來答題。
變通,這一點他學的越來越好了。
只希望他不要成為羊毛黨。
後記
後來,我再也沒有見過 S 君這樣有趣的人。所以我把我教給 S 君的東西,寫成了一本書:《Python 爬蟲開發 從入門到實戰》。希望你也能變成 S 君一樣有趣而又厲害的人。
爬蟲是一門雜學。因為在一個完整的開發過程中,需要涉及到的知識可以包括但不限於:Python,HTML,JavaScript,正則運算式,XPath,資料庫,Redis,訊息佇列,Docker,ELK,Hadoop,資料分析,ETL,中間人攻擊,自動化測試技術,視覺化……
這其中的任何一項,在一個大公司裡面都可以讓很多人來做。
爬蟲開發,就像這篇文章裡面反覆出現的一個詞:變通——只要能夠獲得資料,任何技術都可以使用。所謂草木竹石皆可為劍。爬蟲不應該是一個枯燥的一成不變的樣式化的工作。而是一個充滿了創意和挑戰,能夠讓旁觀者大呼“我 X 還能這樣搞”的工作。
爬蟲開發,絕對不僅僅是 Scrapy,PySpider,requests 這些框架或者庫的使用。所以在這本書裡面,我也刻意減少了框架使用說明的部分,而把重點放在了各種突破反爬蟲機制或者使用變通的方法繞過反爬蟲機制的方法論和實踐中。
透過學習爬蟲,你最後不一定選擇爬蟲工程師這個崗位,但是在學習爬蟲的過程中,你將會接觸到的各種工具,方法,服務元件,都會在你以後的生活和工作中幫到你,讓你知道,在遇到一個問題的時候,解決方法在哪個地方。
最後,介紹一下《Python 爬蟲開發 從入門到實戰》的作者:在網路上的名字叫做青南或者 kingname(青南的音譯)。2014 年加入 Linux 中國的翻譯組 LCTT(所以本文的釋出屬於組內福利哦),2015 年作為極客學院爬蟲課程講師,開設的爬蟲開發課程,受眾超過 10 萬。現在在網易遊戲擔任高階資料挖掘工程師。
不能少的國慶福利
各位同學平時是否也有過本想學一個東西,結果一不小心附帶學了很多東西的經歷呢?歡迎大家留言分享你的經歷。我們在 10 月 8 日將會選出 4 名同學,一人贈送一本作者簽名版的《Python 爬蟲開發 從入門到實戰》~
這本書現在已在京東,噹噹與亞馬遜上架,顯然,你能想到,點選“檢視原文”就能直達 Linux 中國官方書店購買,只是,你不知道的是“檢視原文”可能是最優惠的。
如果已經購買本書,或者對本書有興趣,可以進入本書的讀者交流微信群。進群方式:長按新增公眾號 未聞 Code,回覆“讀者交流”獲取入群方式。公眾號二維碼: