modelandview 可以返回html么_Python: 爬虫网页解析工具lxml.html(一)
狹義上講,爬蟲只負(fù)責(zé)抓取,也就是下載網(wǎng)頁(yè)。而實(shí)際上,爬蟲還要負(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ù))。
所以說,網(wǎng)頁(yè)下載下來只是第一步,還有重要的一步就是數(shù)據(jù)提取。不同的爬蟲想要的數(shù)據(jù)不一樣,提取的數(shù)據(jù)也就不一樣,但提取方法都是類似的。
最簡(jiǎn)單的提取數(shù)據(jù)的方法,就是使用正則表達(dá)式,此種方法簡(jiǎn)單,提取的邏輯也不能復(fù)雜,不然寫出的正則表達(dá)式就晦澀難懂,甚至不能提取復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。
最終,老猿經(jīng)過多年的使用經(jīng)驗(yàn),選擇了lxml和xpath來解析網(wǎng)頁(yè)提取結(jié)構(gòu)化數(shù)據(jù)。順便說一下 BeautifulSoup,它也是一個(gè)很棒的解析HTML的工具,可以使用多個(gè)解析器,比如Python標(biāo)準(zhǔn)庫(kù)的parser,但是速度比較慢,也可以使用lxml作為解析器,但是它的使用方法、API跟lxml不太一樣。使用下來,還是lxml的API更舒服。
lxml 對(duì)C語(yǔ)言庫(kù) libxml2和 libxslt進(jìn)行綁定,提供了Pythonic的API,它有一些主要特點(diǎn):
- 支持標(biāo)準(zhǔn)的XML
 - 支持(損壞)的HTML
 - 非常快的解析速度
 - Pythonic的API更易于使用
 - 使用Python的unicode字符串
 - 內(nèi)存安全(沒有段錯(cuò)誤)
 - 不需要手動(dòng)管理內(nèi)存
 
總結(jié)為一句話就是,C語(yǔ)言的速度和Python的簡(jiǎn)易相結(jié)合的神器。
lxml有兩大部分,分別支持XML和HTML的解析:
- lxml.etree 解析XML
 - lxml.html 解析html
 
lxml.etree可以用來解析RSS feed,它就是一個(gè)XML格式的文檔。然而爬蟲抓取的絕大部分都是html網(wǎng)頁(yè),所以,我們這里主要講述lxml.html解析網(wǎng)頁(yè)的方法。
lxml.html 從html字符串生成文檔樹結(jié)構(gòu)
我們下載得到的網(wǎng)頁(yè)就是一串html字符串,如何把它輸入給lxml.html模塊,從而生成html文檔的樹結(jié)構(gòu)呢?
該模塊提供了幾種不同的方法:
- parse(filename_url_or_file):
 - 輸入的是一個(gè)文件名、URL或文件對(duì)象(有read()方法)。
 - document_fromstring(string):
 - 輸入的是一個(gè)html的字符串,創(chuàng)建一個(gè)HTML文檔樹結(jié)構(gòu),它的根節(jié)點(diǎn)就是, 和 子節(jié)點(diǎn)。
 - fragment_fromstring(string, create_parent=False):
 - 返回輸入字符串的HTML片段。這個(gè)片段壁紙只含有一個(gè)element(元素),也就是單一節(jié)點(diǎn),除非給出了create_parent 參數(shù),否則會(huì)報(bào)錯(cuò)。
 - fragments_fromstring(string):
 - 返回包含輸入字符串中所有片段的列表。
 - fromstring(string):
 - 返回值依據(jù)輸入字符串而定,如果輸入看起來像是一個(gè)文檔,則返回document_fromstring(string),如果是一個(gè)單一片段,則返回fragment_fromstring(string)。
 
下面我們通過具體示例來說明上面幾個(gè)方法的不同。
document_fromstring 的使用方法
In [1]: import lxml.html as lhIn [2]: z = lh.document_fromstring('abcxyz')# 可以看到,它自動(dòng)加了根節(jié)點(diǎn)In [3]: zOut[3]: In [4]: z.tagOut[4]: 'html'# 還加了節(jié)點(diǎn)In [5]: z.getchildren()Out[5]: []# 把字符串的兩個(gè)節(jié)點(diǎn)放在了里面In [6]: z.getchildren()[0].getchildren()Out[6]: [, ]fragment_fromstring 的使用
In [11]: z = lh.fragment_fromstring(‘a(chǎn)bcxyz’)---------------------------------------------------------------------------ParserError Traceback (most recent call last) in ()----> 1 z = lh.fragment_fromstring(‘a(chǎn)bcxyz’)~/.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ù),就沒問題了In [12]: z = lh.fragment_fromstring('abcxyz', create_parent='p')In [13]: z.tagOut[13]: 'p'In [14]: z.getchildren()Out[14]: [, ]fragments_fromstring 的使用
# 輸入字符串含有一個(gè)節(jié)點(diǎn),則返回包含這一個(gè)節(jié)點(diǎn)的列表In [17]: lh.fragments_fromstring('abc')Out[17]: []# 輸入字符串含有多個(gè)節(jié)點(diǎn),則返回包含這多個(gè)節(jié)點(diǎn)的列表In [18]: lh.fragments_fromstring('abcxyz')Out[18]: [, ]fromstring 的使用
In [27]: z = lh.fromstring('abcxyz')In [28]: zOut[28]: In [29]: z.getchildren()Out[29]: [, ]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)開始的,我們使用fromstring() 和 document_fromstring() 都可以得到完整的網(wǎng)頁(yè)結(jié)構(gòu)。
從上面代碼中我們可以看到,那幾個(gè)函數(shù)返回的都是HtmlElement對(duì)象,也就是說,我們已經(jīng)學(xué)會(huì)了如何從html字符串得到HtmlElement的對(duì)象,下一節(jié)我們將學(xué)習(xí)如何操作HtmlElement對(duì)象,從中提取我們感興趣的數(shù)據(jù)。
總結(jié)
以上是生活随笔為你收集整理的modelandview 可以返回html么_Python: 爬虫网页解析工具lxml.html(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: python小案例随机点名_python
 - 下一篇: python程序改错题字符统计_Pyth