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