建立一個網絡爬蟲程序,最重要的事情就是:明確我要抓取什么,以及怎樣抓取。大部分情況下,我們會希望抓取到網頁中包含某些關鍵字的內容或者某些url,首先要實現的是對單個網頁實行抓取。
我們以一個具體的應用為例:如何的得到cnblog中某個人博客中所有隨筆的題目以及連接。
首先,我們要得到需要進行爬蟲操作的網頁地址,通過python系統庫內的urllib2這個Module獲得對應的HTML源碼。
import urllib2 contents = urllib2.urlopen("http://www.baidu.com").read() print contents
通過上面這三句就可以將URL的源碼存在content變量中,其類型為字符型。
如果打印contents,你會發現現實的內容其實就是目標網頁的源代碼,接下來是要從這堆HTML源碼中提取我們需要的內容。
面對如此復雜的網頁源代碼,包含大量的標簽及結構,我們需要一種更加高效方便的形式來完成數據的提取。這里,我們使用BeautifulSoup這個第三方庫,完成數據清洗的工作。
1 from bs4 import BeautifulSoup 2 soup=BeautifulSoup(content) 3 global siteUrls 4 siteUrls = soup.findAll('a',attrs={'class':'postTitle2'}) 5 print siteUrls
siteUrls顯示的內容就是我們需要的信息的初步清洗結果,它提取的是html源碼中class=postTitle2的<a>標簽,結果是一個list,每個元素都對應我們所求的一個url,我們可以對這個list的每個元素進行進一步的清洗,得到需要的url。
1 strip_tag_pat=re.compile('</?\w+[^>]*>') 2 f = file('info.txt','w') 3 for i in siteUrls: 4 i0 = re.sub(strip_tag_pat,' ',str(i)) 5 i1 = str(i).split(' ') 6 #print i1 7 html = i1[2][6:-1] 8 #print html + i0 9 f.write(html+i0+'\n') 10 f.close()
上述代碼中的第一行,
strip_tag_pat=re.compile('</?\w+[^>]*>')
是利用re這個model對list中的每個元素進行去除html標簽的工作,具體的re庫的內容將在以后介紹,大家也可以自行參閱python官方指南。
我們將每個元素中的標簽用空白符替換掉,得到的是每個url的介紹,即每一篇博文的題目,便於我們以后對所需資料的檢索。
然后,我們用split()方法以間隔的空白符為界將每個元素分割成了一個單獨的list,如:
['<a', 'class="postTitle2"', 'href="http://www.cnblogs.com/sayary/archive/2013/02/25/2932552.html"', 'id="homepage1_HomePageDays_DaysList_DayItem_3_DayList_3_TitleUrl_0">\xe3\x80\x90\xe6\xaf\x8f\xe6\x97\xa5\xe4\xb8\x80\xe9\xa2\x98\xe3\x80\x91CareerCup1.8', '\xe5\xad\x97\xe7\xac\xa6\xe4\xb8\xb2\xe5\x9b\x9e\xe8\xbd\xac\xe7\x9a\x84\xe6\xa3\x80\xe9\xaa\x8c</a>']
我們可以看到需要的html在新的List中的第二個位置,通過對list的操作我們可以得到所需的url。
完成的源代碼如下:(以我自己的博客為例)
1 ''' 2 Created on 2013-3-10 3 4 @author: gixiaochen 5 ''' 6 import urllib2 7 from bs4 import BeautifulSoup 8 import re 9 siteUrls = " " 10 11 url = "http://www.cnblogs.com/sayary/" 12 def getContent(url): 13 content = urllib2.urlopen(url).read() 14 #print content 15 16 soup=BeautifulSoup(content) 17 global siteUrls 18 siteUrls = soup.findAll('a',attrs={'class':'postTitle2'}) 19 #nextUrl = soup.find('div',attrs={'class':'topicListFooter'}) 20 #print siteUrls 21 #print str(nextUrl) 22 strip_tag_pat=re.compile('</?\w+[^>]*>') 23 24 f = file('info.txt','w') 25 for i in siteUrls: 26 i0 = re.sub(strip_tag_pat,' ',str(i)) 27 i1 = str(i).split(' ') 28 print i1 29 html = i1[2][6:-1] 30 #print html + i0 31 f.write(html+i0+'\n') 32 f.close() 33 34 35 getContent(url)
我們把所得到的數據保存到了一個txt文件中,當然,我們可以保存到數據庫內。
然而這還不是結束,我們會發現,現在所得到的結果並不是一個人的全部隨筆目錄,而只是隨筆列表中第一頁的內容。
換言之,我們的網絡爬蟲僅僅抓取了某個特定網頁的內容,如何得到所有的隨筆列表?換一個角度來說,如何真正實現爬蟲”爬“的功能,讓他能夠抓取到我們所需的全部信息呢?下一節我們會具體討論網路爬蟲中的各種爬取的方法,如廣度優先算法等。