數(shù)據(jù)的意義在于從中發(fā)現(xiàn)有趣的事情,以了解這個(gè)世界,體驗(yàn)一種創(chuàng)造性的快樂(lè)。我對(duì)豆瓣很有興趣,它很特別,在國(guó)內(nèi)外沒(méi)有可類比的公司。對(duì)它的探究,要從研究豆瓣的用戶開(kāi)始。
如果要研究豆瓣的用戶,先要抓取豆瓣的用戶信息。豆瓣的用戶的主頁(yè)形如:http://www.douban.com/people/laoluo/,這個(gè)是老羅的豆瓣主頁(yè),在右下角有“羅永浩的關(guān)注”,里面有他關(guān)注的8個(gè)用戶。
如果想抓豆瓣,最簡(jiǎn)單的方式是,從任意一個(gè)用戶開(kāi)始,比如老羅,先抓取http://www.douban.com/people/laoluo/,把頁(yè)面存起來(lái),然后找到他關(guān)注的8個(gè)用戶,記下ta們的用戶ID,然后再抓取ta們的主頁(yè),再找他們關(guān)注的用戶,循環(huán)不斷地抓下去,幾乎可以抓取豆瓣用戶的所有用戶。
我試了幾種開(kāi)源的Java爬蟲(chóng),有的叫spider,有的叫crawler,其實(shí)意思都一樣,業(yè)內(nèi)常用的是Nutch,但體量有點(diǎn)大,粗略看了下代碼有幾萬(wàn)行,讀它的代碼可能比較耗時(shí)。最后選了crawler4j,它的代碼量只有幾千行,然后用它的庫(kù)寫(xiě)了一個(gè)定制版的豆瓣crawler,從任意一個(gè)用戶主頁(yè)開(kāi)始抓豆瓣的用戶資料。定制crawler用了兩個(gè)線程,一個(gè)線程負(fù)責(zé)抓頁(yè)面,一個(gè)線程負(fù)責(zé)把數(shù)據(jù)存到硬盤。不好用多個(gè)線程抓--豆瓣的 robots.txt即http://www.douban.com/robots.txt的指定抓取延遲不小于5秒,抓太快了會(huì)被禁掉的,這種情況下抓一個(gè)用戶要用6秒時(shí)間,一天能抓60/6*60*24=14400個(gè),一個(gè)月能抓43萬(wàn)個(gè)用戶,豆瓣注冊(cè)用戶有6000萬(wàn),需要139個(gè)機(jī)月,也就是139臺(tái)機(jī)器抓一個(gè)月。如果在云上租139臺(tái)機(jī)器,一個(gè)月的總成本大概是139*60=8340 塊,租一臺(tái)入門級(jí)的機(jī)器一個(gè)月60塊搞得定的,做抓取綽綽有余,只是要把crawler改成分布式的才行。每個(gè)用戶頁(yè)面大概60k左右,1G存儲(chǔ)1.7萬(wàn)個(gè)用戶,6000萬(wàn)用戶的容量不到4T。抓取線程要考慮主動(dòng)注銷的用戶,存儲(chǔ)線程要考慮單個(gè)目錄的最大文件容量,默認(rèn)每個(gè)目錄存1000個(gè)文件即可。定制 crawler用糙快猛的方式搞定的,大概500多行代碼。話說(shuō)8千塊抓豆瓣的所有用戶資料不知道值不值,我覺(jué)得挺值的---應(yīng)該有很多好東西可以算出來(lái)的,隨隨便便搞出來(lái)賣分析報(bào)告也能值這個(gè)價(jià)啊,還可以賣給好幾家呢。如果要抓所有的用戶關(guān)系花時(shí)間要更多了---關(guān)注者是分頁(yè)的,想做類似 Facebook的graph search需要抓更多的頁(yè)面。
大概抓到5萬(wàn)個(gè)用戶的時(shí)候,我就開(kāi)始做計(jì)算了,用 htmlcleaner+jython處理頁(yè)面文件,最關(guān)鍵是找到ta們被多少人關(guān)注,被關(guān)注數(shù)表明它們的重要性。盡管5萬(wàn)個(gè)用戶對(duì)6000萬(wàn)個(gè)全部用戶來(lái)說(shuō)太少了,還有有一些規(guī)律的---此前有一個(gè)關(guān)注榜,記錄的是關(guān)注在5000以上的豆瓣達(dá)人,它是2012年出來(lái)的,在這里http://site.douban.com/144692/widget/forum/7144906/discussion/44924707/,我的結(jié)果跟它有相當(dāng)一部分的重合,可見(jiàn)盡管樣本數(shù)量少也是有效果的。