狹義上講,爬蟲(chóng)只負(fù)責(zé)抓取,也就是下載網(wǎng)頁(yè)。而實(shí)際上,爬蟲(chóng)還要負(fù)責(zé)從下載的網(wǎng)頁(yè)中提取我們想要的數(shù)據(jù),即對(duì)非結(jié)構(gòu)化的數(shù)據(jù)(網(wǎng)頁(yè))進(jìn)行解析提取出結(jié)構(gòu)化的數(shù)據(jù)(有用數(shù)據(jù))。比如,我們要抓取了一個(gè)新聞頁(yè)面的網(wǎng)頁(yè)(html)下來(lái),但我們想要的是這個(gè)網(wǎng)頁(yè)中關(guān)于新聞的結(jié)構(gòu)化數(shù)據(jù):新聞的標(biāo)題、新聞的發(fā)布時(shí)間、新聞的正文等。
十年的漢中網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷(xiāo)的優(yōu)勢(shì)是能夠根據(jù)用戶(hù)設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整漢中建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)公司從事“漢中網(wǎng)站設(shè)計(jì)”,“漢中網(wǎng)站推廣”以來(lái),每個(gè)客戶(hù)項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
所以說(shuō),網(wǎng)頁(yè)下載下來(lái)只是第一步,還有重要的一步就是數(shù)據(jù)提取。不同的爬蟲(chóng)想要的數(shù)據(jù)不一樣,提取的數(shù)據(jù)也就不一樣,但提取方法都是類(lèi)似的。
最簡(jiǎn)單的提取數(shù)據(jù)的方法,就是使用正則表達(dá)式,此種方法簡(jiǎn)單,提取的邏輯也不能復(fù)雜,不然寫(xiě)出的正則表達(dá)式就晦澀難懂,甚至不能提取復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。
經(jīng)過(guò)多年的使用經(jīng)驗(yàn),選擇了lxml和xpath來(lái)解析網(wǎng)頁(yè)提取結(jié)構(gòu)化數(shù)據(jù)。順便說(shuō)一下 BeautifulSoup,它也是一個(gè)很棒的解析HTML的工具,可以使用多個(gè)解析器,比如Python標(biāo)準(zhǔn)庫(kù)的parser,但是速度比較慢,也可以使用lxml作為解析器,但是它的使用方法、API跟lxml不太一樣。使用下來(lái),還是lxml的API更舒服。
lxml 對(duì)C語(yǔ)言庫(kù) libxml2和 libxslt進(jìn)行綁定,提供了Pythonic的API,它有一些主要特點(diǎn):
總結(jié)為一句話就是,C語(yǔ)言的速度和Python的簡(jiǎn)易相結(jié)合的神器。
lxml有兩大部分,分別支持XML和HTML的解析:
lxml.etree可以用來(lái)解析RSS feed,它就是一個(gè)XML格式的文檔。然而爬蟲(chóng)抓取的絕大部分都是html網(wǎng)頁(yè),所以,我們這里主要講述lxml.html解析網(wǎng)頁(yè)的方法。
我們下載得到的網(wǎng)頁(yè)就是一串html字符串,如何把它輸入給lxml.html模塊,從而生成html文檔的樹(shù)結(jié)構(gòu)呢?
該模塊提供了幾種不同的方法:
document_fromstring(string)
,如果是一個(gè)單一片段,則返回
fragment_fromstring(string)
。下面我們通過(guò)具體示例來(lái)說(shuō)明上面幾個(gè)方法的不同。
In [1]: import lxml.html as lh In [2]: z = lh.document_fromstring('<span>abc</span><span>xyz</span>') # 可以看到,它自動(dòng)加了根節(jié)點(diǎn)<html> In [3]: z Out[3]: <Element html at 0x7fc410667b88> In [4]: z.tag Out[4]: 'html' # 還加了<body>節(jié)點(diǎn) In [5]: z.getchildren() Out[5]: [<Element body at 0x7fc4101a3ae8>] # 把字符串的兩個(gè)節(jié)點(diǎn)放在了<body>里面 In [6]: z.getchildren()[0].getchildren() Out[6]: [<Element span at 0x7fc410092bd8>, <Element span at 0x7fc410667c28>]
In [11]: z = lh.fragment_fromstring(‘<div>abc</div><div>xyz</div>’) --------------------------------------------------------------------------- ParserError Traceback (most recent call last) <ipython-input-11-a11f9a0f71d1> in <module>() ----> 1 z = lh.fragment_fromstring(‘<div>abc</div><div>xyz</div>’) ~/.virtualenvs/py3.6/lib/python3.6/site-packages/lxml/html/__init__.py in fragment_fromstring(html, create_parent, base_url, parser, **kw) 850 raise etree.ParserError( 851 “Multiple elements found (%s)” --> 852 % ‘, ‘.join([_element_name(e) for e in elements])) 853 el = elements[0] 854 if el.tail and el.tail.strip(): ParserError: Multiple elements found (div, div) # 可以看到,輸入是兩個(gè)節(jié)點(diǎn)(element)時(shí)就會(huì)報(bào)錯(cuò) # 如果加上 create_parent 參數(shù),就沒(méi)問(wèn)題了 In [12]: z = lh.fragment_fromstring('<div>abc</div><div>xyz</div>', create_parent='p') In [13]: z.tag Out[13]: 'p' In [14]: z.getchildren() Out[14]: [<Element div at 0x7fc40a41a818>, <Element div at 0x7fc40a41aea8>]
# 輸入字符串含有一個(gè)節(jié)點(diǎn),則返回包含這一個(gè)節(jié)點(diǎn)的列表 In [17]: lh.fragments_fromstring('<div>abc</div>') Out[17]: [<Element div at 0x7fc40a124ea8>] # 輸入字符串含有多個(gè)節(jié)點(diǎn),則返回包含這多個(gè)節(jié)點(diǎn)的列表 In [18]: lh.fragments_fromstring('<div>abc</div><div>xyz</div>') Out[18]: [<Element div at 0x7fc40a124b88>, <Element div at 0x7fc40a124f98>]
In [27]: z = lh.fromstring('<div>abc</div><div>xyz</div>') In [28]: z Out[28]: <Element div at 0x7fc40a0eb368> In [29]: z.getchildren() Out[29]: [<Element div at 0x7fc410135548>, <Element div at 0x7fc40a0eb2c8>] In [30]: type(z) Out[30]: lxml.html.HtmlElement
這里,fromstring輸入的如果是多個(gè)節(jié)點(diǎn),它會(huì)給加一個(gè)父節(jié)點(diǎn)并返回。但是像html網(wǎng)頁(yè)都是從節(jié)點(diǎn)開(kāi)始的,我們使用fromstring() 和 document_fromstring() 都可以得到完整的網(wǎng)頁(yè)結(jié)構(gòu)。
從上面代碼中我們可以看到,那幾個(gè)函數(shù)返回的都是HtmlElement對(duì)象,也就是說(shuō),我們已經(jīng)學(xué)會(huì)了如何從html字符串得到HtmlElement的對(duì)象,下一節(jié)我們將學(xué)習(xí)如何操作HtmlElement對(duì)象,從中提取我們感興趣的數(shù)據(jù)。
新聞名稱(chēng):Python爬蟲(chóng)網(wǎng)頁(yè),解析工具lxml.html(一)
轉(zhuǎn)載來(lái)于:http://m.newbst.com/article38/jicipp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開(kāi)發(fā)、品牌網(wǎng)站設(shè)計(jì)、App開(kāi)發(fā)、網(wǎng)站設(shè)計(jì)公司、網(wǎng)站建設(shè)、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)