最近需要收集資料,在瀏覽器上用另存為的方式實(shí)在是很麻煩,而且不利于存儲(chǔ)和檢索。所以自己寫(xiě)了一個(gè)小爬蟲(chóng),在網(wǎng)上爬東西,迄今為止,已經(jīng)爬了近百萬(wàn)張網(wǎng)頁(yè)。
現(xiàn)在正在想辦法著手處理這些數(shù)據(jù)。
爬蟲(chóng)的結(jié)構(gòu):
爬蟲(chóng)的原理其實(shí)很簡(jiǎn)單,就是分析下載的頁(yè)面,找出其中的連接,然后再下載這些鏈接,再分析再下載,周而復(fù)始。在數(shù)據(jù)存儲(chǔ)方面,數(shù)據(jù)庫(kù)是首選,便于檢索,而開(kāi)發(fā)語(yǔ)言,只要支持正則表達(dá)式就可以了,數(shù)據(jù)庫(kù)我選擇了mysql,所以,開(kāi)發(fā)腳本我選擇了php。它支持perl兼容正則表達(dá)式,連接mysql很方便,支持http下載,而且windows系統(tǒng)和linux系統(tǒng)都可以部署。
正則表達(dá)式:
正則表達(dá)式是處理文字的基本工具,要取出html中的鏈接和圖片,使用的正則表達(dá)式如下。
"#<a[^>]+href=(['\"])(.+)\\1#isU" 處理鏈接
"#<img[^>]+src=(['\"])(.+)\\1#isU" 處理圖片
其他問(wèn)題:
寫(xiě)爬蟲(chóng)還需要注意的一個(gè)問(wèn)題是,對(duì)于已經(jīng)下載過(guò)的url,不能重復(fù)進(jìn)行下載,而有些網(wǎng)頁(yè)的鏈接會(huì)形成環(huán)路,所以需要處理這個(gè)問(wèn)題,我的處理方法是計(jì)算已經(jīng)處理的url的MD5 值,并存入數(shù)據(jù)庫(kù),這樣就可以檢驗(yàn)是否已經(jīng)下載過(guò)。當(dāng)然還有更好的算法,有興趣的話,可以在網(wǎng)上找一下。
相關(guān)協(xié)議:
爬蟲(chóng)也有自己的協(xié)議,有個(gè)robots.txt文件定義了那些是網(wǎng)站允許遍歷的,但是由于我的時(shí)間有限,沒(méi)有實(shí)現(xiàn)這個(gè)功能。
其他說(shuō)明:
php支持類編程,我寫(xiě)的爬蟲(chóng)主要的類.
1.url處理web_site_info,主要用處理url,分析域名等。
2.數(shù)據(jù)庫(kù)操作mysql_insert.php,處理和數(shù)據(jù)庫(kù)相關(guān)的操作。
3.歷史記錄處理,記錄已經(jīng)處理的url。
4.爬蟲(chóng)類。
存在的問(wèn)題和不足
這個(gè)爬蟲(chóng)在小數(shù)據(jù)量的情況下,運(yùn)行良好,但是在大數(shù)據(jù)量的情況下,歷史記錄處理類的效率就不是很高,通過(guò)在數(shù)據(jù)庫(kù)結(jié)構(gòu)中,對(duì)相關(guān)字段進(jìn)行了索引,速度有了提高,但是需要不斷得讀取數(shù)據(jù),可能和php本身的array實(shí)現(xiàn)有關(guān)系,如果一次加載10萬(wàn)條歷史記錄,速度非常慢。
不支持多線程,每次只能處理一個(gè)url。
php運(yùn)行本身有內(nèi)存使用量限制,有一次在抓取深度為20的頁(yè)面的時(shí)候,內(nèi)存用盡程序被殺。
下面的url是源碼下載。
http://www.shnenglu.com/Files/hdqqq/net_spider.rar
使用的時(shí)候,先在mysql中創(chuàng)建net_spider數(shù)據(jù)庫(kù),然后用db.sql創(chuàng)建相關(guān)表。再在config.php中設(shè)置mysql的用戶名口令。
最后
php -f spider.php 深度(數(shù)值) url
就可以開(kāi)始工作。如
php -f spider.php 20 http://news.sina.com.cn
現(xiàn)在感覺(jué)下來(lái),其實(shí)做個(gè)爬蟲(chóng)沒(méi)那么復(fù)雜,難的是數(shù)據(jù)的存儲(chǔ)和檢索。我現(xiàn)在的數(shù)據(jù)庫(kù),最大一個(gè)數(shù)據(jù)表已經(jīng)15G,正在想辦處理這些數(shù)據(jù),mysql進(jìn)行查詢已經(jīng)感覺(jué)有點(diǎn)力不從心了。這點(diǎn)上還真佩服google。