記錄我與DHT爬蟲那些激情歲月
2013年10月份某一天,從搬磚的工地回到辦公室,甩掉破了幾個洞的手套,解下油膩膩的安全帽,打開已有7,8年使用歷史的IBM筆記本電腦,灰暗無光的眼睛瞬間變得精亮精亮的(我從屏幕反光看到),叼著娃哈哈,進入博客園看有木有干貨出現,鬼使神差地進入了小蝦的個人博客,看到了那篇關于DHT的文章,發現dianying.fm是他的杰作,當時把我激動得……事情回到5月份,當時我想做一個跟dianying.fm類似的網站,當時采取的是把他資源給扒下來,但是后來給放棄了,個人覺得,扒別人的資源來做資源站顯得沒技術含量。 所以一直就掛在心上,時不時地在琢磨他是怎么辦到的。 很笨的是,居然沒寫信問他是如何做到的。 也不知道他的個人博客。
時隔5個月后,終于發現了這個秘密,于是就開始研究DHT,但是國內關于DHT文章少得可憐,根本就沒幾個人在研究(這更使我覺得要是實現了會更有成就感),加之根本就看不懂英文官方文檔。 對DHT也是一知半解,當時一直以為DHT的"distance metric"指的就是實際地理距離,也一直以為如果把爬蟲放到日本地區的話,會爬取到更多的AV視頻。 于是只好借用別人DHT爬蟲(dhtcrawler),用了一段時間,始終不滿意它的通過HTTP請求種子下載方式,而且一點成就感都沒有,畢竟爬蟲代碼不是自己寫的。 貌似dhtcrawler的作者也在博客園來著,嘿嘿! 于是下定決心學英語(本人初中畢業,在學校幾乎沒學過英語),一定要寫一個屬于自己的DHT爬蟲。 于是開始閉關修煉,不再上QQ閑扯蛋。
接著開始狠看Python中英對照技術文檔練英語,看了差不多半個月,了解了一些技術文檔常用的語法。 還把DHT官方文檔不認識的單詞給背了。 棄掉用了一兩年的PHP這個只擅長web端編程語言,改用NodeJS,看上了它那事件編程,后來發現寫的代碼實在難以理解,嵌套太深,"內涵"太低,改用Perl,學了一周就上馬了,一開始用著還不錯,一兩行代碼頂NodeJS和PHP十幾行代碼,但就是因為太強悍了,駕馭不了它那亂七八糟的^$#@_*~%什么的符號,一眼望去,整篇代碼丑陋不堪(咋一看還挺高深的樣),依靠上下文環境的代碼太多。 于是打算換其他的編程語言,花了幾天就是找不到順手的。 C像個巫婆,法力大,脾氣怪,Java"官僚化",太繁瑣,C#只支持Windows(雖然Linux有mono)。 Lisp深不可測,erlang看不懂,語法怪。 Ruby更是怪。 一時陷入世界這么大,無編程語言可用的狀態,一連好幾天搬磚都沒精神,好幾次都差點被落下的建筑物給砸到。
后來猛地想起還有個叫Python這個動態語言,于是趕緊地看手冊,草草學了一周,發現用著還真順手,好用得我只能說"爽爆了!"。 它那異常處理很自然,不像PHP那樣硬生生的; 也不像Java那樣太繁瑣; 有點像Lisp/Haskell,雖然一點都不會,不過特別喜歡里面的某些風格,比如那lambda,list comps; 還有自己的shell,語法簡單無比; 庫也特別多,讓我這個不愛寫小工具的懶人真是個寶貝; 于是你們懂得。 我就成了Python的教徒了。 以前用PHP的那一兩年,從未有這么個"宗教感"。
上述毫無挑起語言宗教戰爭的意思,請勿對號入座,只是激動了點!
接著開始了解Python的多線程,事件編程,各種各樣的web框架,模板,挑出Flask,jinja這倆玩意兒來做web開發,文檔簡單例子多,推薦那些用Django的人試試Flask,不知是不是名字太過火爆,官網都要靠翻墻。 jianja模板引擎跟PHP的Symfony2的默認模板引擎Twig非常相似,干貨一個,話說好知網都是用的Symfony2。 然后學習Twisted網絡框架,這個玩意兒只有英語文檔,寫得不是很通順,讓我費了很大的勁才學懂一點點,還不錯! 只是感覺事件編程沒有NodeJS那么自然。 轉眼就到了12月份,天氣冷得在野外撒尿都掏不出JJ; 于是全部放假回家,回到家,猛騎了幾天的稀泥山地車活躍身體,就開始閉關修煉專攻DHT。 因為第一次看協議類的文檔,總感覺協議文檔很虛無,很容易讓人忘記是在看協議而不是在看手冊,一點樣例代碼都沒。 有點頭大,不過放棄這么意思的協議實現不是我的風格,所以還是硬著頭皮仔仔細細地看文檔,好不容易懂了概念,就開始coding了,因為對DHT還不是很熟,所以代碼寫了推,推了寫,一直都沒多少效果,于是就搞了幾個開源代碼看,看了幾個后,豁然開朗。 后來總算搞出一個可以運行的版本。 又花了幾天重新整了下代碼。 總算實現了DHT爬蟲: https://github.com/laomayi/simDHT 簡單粗暴不做作! 這個是要做類似dianying.fm的發動機。
霉運正式開始:
由于是在Linux環境下編寫,有次不小心刪掉了所有代碼,當時感覺腦袋一黑,臉通紅,頭冒汗,腿打擺子,心想: 完鳥完鳥,我幾個月的代碼就這么完鳥,頭一次體會到一國外牛說的"rm -rf *。log"就是個錯誤設計的內涵了(我在"*" 和"。log"之間不小心空了一格)。 緩了一會,蛋定地睡覺去了,之所以這么蛋定,是因為稍后想到寫了無數次,代碼構造都差不多能背下來了,不急,再加上編輯器還緩存著幾個文件代碼,復制粘貼來,最主要的是代碼又很精簡。 第二天騎著我那巨無霸山地車到了親戚家聚會,花了一兩個小時給寫了回來。 順便向一用Java,站在我旁邊看我coding的美女炫耀了一番我程序,把她驚奇得一個勁兒地問我一臺電腦怎么可能認識幾百萬,幾千萬的電腦? 怎么可能把他們電腦的共享資源給收集下來? 怎么可能你服務器就只記錄這么點信息? 怎么可能服務器還不用承受資源下載負擔? 還問我的什么語言,代碼看起來一點不像代碼? 我都一一自豪又耐心地回答。 我也看了她那Java寫的代碼,寫得很搞笑,都是些Dog/Cat/Master/Food Class什么的,好吧,她是個大學生,那些都是跟著他們老師寫的。 也順便給她說了句,設計模式要穩打穩扎地學,學得隨手拈來才接下一個,免得像邯鄲學步,都忘了如何走路,趴著回來,多看看開源代碼,少看點爛書。 話說,在聚會時,人人都在玩游戲,而你戴著一副防光鏡編程,是一件多么拉風的事情。 當然也有人明著暗著說編程有個毛線用,我一笑了之。 借用Zed A。 Shaw說的: 當有人說你編程像個怪物,不隨大眾,與眾不同,甚至因戳穿了他們的邏輯漏洞而他們開始和你爭辯,不用鳥他們,他們只是嫉妒你掌握了他們做夢都不能得到的技能而已,要記住這是你的旅程,不是他們的。 后來吸取經驗,整了個bitbucket來做備份,私有代碼免費滴。
實現了DHT還不夠,得想辦法弄到種子文件,只有這樣才能做一個資源下載站,看了很多開源DHT爬蟲程序,要么沒實現,要么就是通過HTTP向別的種子站下載,這方式對我來說,有種危機感,萬一那種子站關閉了咋辦? 而且沒成就感有木有? 所以還是要自己實現協議整一個BT客戶端,看了好幾天協議文檔,還是搞不懂怎么實現,借鑒的也只有libtorrent,但是太龐大,C/C++語言又不是很熟悉,所以暫時把它當庫在Python里調用,好歹也是靠自己去DHT網絡下載的,比那些使用HTTP下別人的種子強多了。 等休息一段時間再來研究,連續4,5個月沒怎么好好休息了。
后來,一件件讓我發瘋的事情出現,我買的3G無線網卡居然停機了,沒法測試種子下載部分代碼。 于是只好帶著筆記本到我們這鄉村唯一的網吧去上網,使用小米的網絡共享,開啟熱點。 霉運未就此打住,連上USB不能直接使用網絡共享,得安裝小米助手,但是小米助手里有驅動,很多網吧可是禁止安裝驅動,一安立馬重啟,重啟后可啥都沒了,后來鼓搗鼓搗,把那小米安裝文件設置成windows 2000兼容模式,搞定,只是不穩定,易崩潰。 霉運又接著開始,根本就沒法進行ICMP和UDP(網吧電腦可以),始終不了解原因。 后來把之前用來測試DHT那部分的阿里云主機搞來,在那上面測試,由于不支持Gentoo(諧音"賤兔"),那些Ubuntu,CentOS,Debian真的很難用有木有,使用包管理自定義個軟件安裝參數都不支持(就是像源代碼安裝configure自定義參數那樣,可以開啟什么關閉什么的),軟件源又老,雖然Debian/Ubuntu可以ppa什么的,使用源代碼安裝又有那么多的依賴要整。 花了好長時間都沒搞定,棄用之。
真疑惑國外那么流行的Gentoo為什么在國內得不到重視? 是不是Gentoo太低調了? 還是Gentoo咋一看很難用? 在國內也僅知道晉江文學城,豆瓣,知乎在用Gentoo。 后兩者還用的是Python做web端開發。 于是乎又到budgetvm開了個VPS,支持Gentoo,這個更讓我發瘋,始終無法啟動,問他們神馬原因,居然說Gentoo template出了問題,在修復。 建議我用Ubuntu/CentOS/Debian神馬的,我要是愛用這倆,我還到你那干嗎? 由于僅會閱讀英語,不擅長寫,沒法用長一點的英語"批評"他們。 于是回復等待他們修。 第一通宵就繼續研究我電腦為嘛無法UDP/ICMP(這可不是神馬防火墻,殺毒軟件的問題,我是裸奔的,知道的大神指教下,只有在借助于小米手機電腦網絡共享才會這樣,連接真正的無線路由器可不會這樣)
第三天晚,還是沒收到budgetvm給我的Gentoo template修好就給我Email的信息,我當時就在想,國外的客服說不定也像國內一樣,敷衍了事。 于是又冒雨翻山越嶺去了網吧,打開budgetvm,能啟動Gentoo了,真不敬業,說好要通知的。 可是。。。可是為嘛不能SSH? 連網吧電腦ping都不能ping? 提交ticket詢問之,沒給我解決,一氣之下,又棄之! 我算是死心了,只好到城里再說了。 短時間可找不到價格便宜,支持Gentoo,支付寶的VPS。 于是坐在網吧那下幾個電影放松放松。 感謝我一兄弟,陪我熬了倆通宵,受不了通宵,一直躺在我大腿上睡覺,幸好帶了被子,這里很冷的有木有? 更丟臉的是,因錢包忘在老家,網費都是他付的。 話說我教他前端編程,不過他人太帥,人緣好,事多,無法專心,沒學會。
在工地的最后兩個月是我人生最邋遢的日子,白天搬磚,晚上coding。 為省時間,兩個月不洗澡,不洗頭,洗腳都是涼水沖沖,臟衣服積累了幾十斤,在工地休息時也處于神游狀態。 話說工地上那些人要不是看過我在黑洞洞屏幕前編寫代碼的那"神秘感",都以為我腦子不正常來著,怪不得工地上的一癡呆小工都喜歡和我說話。
寫這個程序給我帶來幾個好處:
0,編程技能上升一個等級,都不敢直視以前那些亂用各種各樣的設計模式混在一堆四不像PHP代碼;
1,英語被逼到能看懂技術文檔,爽歪了我,更加熱愛英語了;
2,成了Python教徒,話說無"宗教感"的程序員不是好程序員,哈哈,這當然不是說程序員要被編程語言所禁錮,要根據不同的項目選用合適的語言;
最后,我想說一句: 你會編程,他們不會,這真tmd的酷!