安裝Beautiful Soup
Beautiful Soup是一個(gè)Python的HTML解析框架墩朦,我們可以利用它方便的處理HTML和XML文檔坯认。Beautiful Soup有3和4兩個(gè)版本,目前3已經(jīng)停止開(kāi)發(fā)氓涣。所以我們當(dāng)然還是學(xué)習(xí)最新的Beautiful Soup 4.
首先第一件事情就是利用pip安裝Beautiful Soup牛哺。我們使用下面的命令。
pip install beautifulsoup4
稍等片刻之后Beautiful Soup就安裝好了劳吠。這樣引润,我們就可以開(kāi)始使用它了。如果需要詳細(xì)文檔的話可以參考Beautiful Soup中文文檔痒玩,這是難得的不是機(jī)翻的文檔淳附。
解析文檔
獲取文檔
Beautiful Soup只是一個(gè)HTML解析庫(kù),所以我們?nèi)绻虢馕鼍W(wǎng)上的內(nèi)容蠢古,第一件事情就是把它下載下來(lái)奴曙。對(duì)于不同的網(wǎng)站,可能會(huì)對(duì)請(qǐng)求進(jìn)行過(guò)濾草讶。糗事百科的網(wǎng)站就對(duì)沒(méi)有UA的請(qǐng)求直接拒絕掉洽糟。所以如果我們要爬這樣的網(wǎng)站,首先需要把請(qǐng)求偽裝成瀏覽器的樣子。具體網(wǎng)站具體分析脊框,經(jīng)過(guò)我測(cè)試颁督,糗事百科只要設(shè)置了UA就可以爬到內(nèi)容践啄,對(duì)于其他網(wǎng)站浇雹,你需要測(cè)試一下才能確定什么設(shè)置能管用。
有了Request對(duì)象還不行屿讽,還需要實(shí)際發(fā)起請(qǐng)求才行昭灵。下面代碼的最后一句就使用了Python3的urllib庫(kù)發(fā)起了一個(gè)請(qǐng)求。urlopen(req)
方法返回的是Reponse對(duì)象伐谈,我們調(diào)用它的read()
函數(shù)獲取整個(gè)結(jié)果字符串烂完。最后調(diào)用decode('utf-8')
方法將它解碼為最終結(jié)果,如果不調(diào)用這一步诵棵,漢字等非ASCII字符就會(huì)變成\xXXX
這樣的轉(zhuǎn)義字符抠蚣。
import urllib.request as request
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
headers = {'User-Agent': user_agent}
req = request.Request('http://www.qiushibaike.com/', headers=headers)
page = request.urlopen(req).read().decode('utf-8')
查詢和遍歷方法
有了文檔字符串,我們就可以開(kāi)始解析文檔了履澳。第一步是建立BeautifulSoup
對(duì)象嘶窄,這個(gè)對(duì)象在bs4模塊中。注意在建立對(duì)象的時(shí)候可以額外指定一個(gè)參數(shù)距贷,作為實(shí)際的HTML解析器柄冲。解析器的值可以指定html.parser
,這是內(nèi)置的HTML解析器忠蝗。更好的選擇是使用下面的lxml
解析器现横,不過(guò)它需要額外安裝一下,我們使用pip install lxml
就可以安裝阁最。
import bs4
soup = bs4.BeautifulSoup(page, "lxml")
有了BeautifulSoup
對(duì)象戒祠,我們就可以開(kāi)始解析了。首先先來(lái)介紹一下BeautifulSoup的對(duì)象種類速种,常用的有標(biāo)簽(bs4.element.Tag
)以及文本(bs4.element.NavigableString
)得哆。還有注釋等對(duì)象,不過(guò)不太常用哟旗,所以就不介紹了贩据。在標(biāo)簽對(duì)象上,我們可以調(diào)用一些查找方法例如find_all
等等闸餐,還有一些屬性返回標(biāo)簽的父節(jié)點(diǎn)饱亮、兄弟節(jié)點(diǎn)、直接子節(jié)點(diǎn)舍沙、所有子節(jié)點(diǎn)等近上。在文本對(duì)象上,我們可以調(diào)用.string
屬性獲取具體文本拂铡。
然后來(lái)說(shuō)說(shuō)BeautifulSoup的遍歷方法壹无〈腥蓿基本所有操作都需要通過(guò)BeautifulSoup
對(duì)象來(lái)使用。使用方式主要有兩種:一是直接引用屬性斗锭,就是soup.title
這樣的地淀,會(huì)返回第一個(gè)符合條件的節(jié)點(diǎn);二是通過(guò)查找方法例如find_all
這樣的岖是,傳入查詢條件來(lái)查找結(jié)果帮毁。
再來(lái)說(shuō)說(shuō)查詢條件。查詢條件可以是:字符串豺撑,會(huì)返回對(duì)應(yīng)名稱的節(jié)點(diǎn)烈疚;正則表達(dá)式,按照正則表達(dá)式匹配聪轿;列表爷肝,會(huì)返回所有匹配列表元素的節(jié)點(diǎn);真值True
陆错,會(huì)返回所有標(biāo)簽節(jié)點(diǎn)灯抛,不會(huì)返回字符節(jié)點(diǎn);方法危号,我們可以編寫(xiě)一個(gè)方法牧愁,按照自己的規(guī)則過(guò)濾,然后將該方法作為查詢條件外莲。本來(lái)還想寫(xiě)詳細(xì)一點(diǎn)猪半,但是由于有中文文檔,所以我還是不寫(xiě)了偷线。直接看關(guān)于查詢的文檔就好了磨确。我還發(fā)現(xiàn)一篇不錯(cuò)的博文,大家可以參考一下声邦,這篇博文介紹的更詳細(xì)乏奥。
實(shí)際例子
爬取糗事百科段子
首先打開(kāi)糗事百科網(wǎng)站,按F12打開(kāi)開(kāi)發(fā)人員工具亥曹,然后在旁邊點(diǎn)擊分離按鈕把它變成獨(dú)立窗口邓了,然后切到元素標(biāo)簽并最大化窗口。然后點(diǎn)擊那個(gè)鼠標(biāo)按鈕媳瞪,再返回糗事百科頁(yè)面骗炉,并點(diǎn)擊一個(gè)段子,這樣就可以查看段子在HTML文檔的什么位置了蛇受。
首先分析一下HTML代碼句葵,然后我們就可以查找所需的內(nèi)容了。這里需要說(shuō)明一下,查詢方法返回的是結(jié)果集乍丈,對(duì)結(jié)果集遍歷可以得到標(biāo)簽或者文本對(duì)象剂碴。如果調(diào)用標(biāo)簽對(duì)象的.contents
,會(huì)返回一個(gè)列表轻专,列表內(nèi)是標(biāo)簽忆矛、文本或注釋對(duì)象。動(dòng)態(tài)語(yǔ)言的優(yōu)勢(shì)就是使用靈活铭若,缺點(diǎn)就是沒(méi)有代碼提示洪碳。雖然總共代碼沒(méi)幾行递览,但是還是花了我一番功夫叼屠。
divs = soup.find_all('div', class_='article block untagged mb15')
for div in divs:
links = div.find_all('a', href=re.compile(r'/article/\d*'), class_='contentHerf')
for link in links:
contents = link.span.contents
contents = [i for i in contents if not isinstance(i, bs4.element.Tag)]
print(contents)
上面的代碼會(huì)輸出首頁(yè)的所有段子。這樣我們便實(shí)現(xiàn)了半個(gè)爬蟲(chóng)绞铃。為什么是半個(gè)呢镜雨?因?yàn)橐粋€(gè)完整的爬蟲(chóng)可以爬取多個(gè)頁(yè)面,為了簡(jiǎn)便這里只爬首頁(yè)儿捧,所以只能算半個(gè)爬蟲(chóng)荚坞。不過(guò)如果你想爬取多個(gè)頁(yè)面,代碼稍加修改即可實(shí)現(xiàn)菲盾。
百度貼吧樓層
本來(lái)還想寫(xiě)一個(gè)爬取百度貼吧樓層的爬蟲(chóng)颓影。但是一看百度貼吧的HTML代碼,我感覺(jué)這個(gè)功能好像比較復(fù)雜懒鉴,所以就不做了……喜歡挑戰(zhàn)的同學(xué)可以試試看诡挂。
BeautifulSoup是一個(gè)HTML/XML 解析庫(kù),可以解析并修改HTML和XML文檔临谱。不過(guò)一般人都用它來(lái)解析網(wǎng)頁(yè)實(shí)現(xiàn)爬蟲(chóng)璃俗。不過(guò)既然有中文文檔,所以如果你想用它來(lái)操作XML文件悉默,照著文檔寫(xiě)就行了城豁。這里就不作介紹了。