天天看點

python爬蟲網頁解析器怎麼寫_Python 爬蟲網頁解析工具lxml.html(一)

狹義上講,爬蟲隻負責抓取,也就是下載下傳網頁。而實際上,爬蟲還要負責從下載下傳的網頁中提取我們想要的資料,即對非結構化的資料(網頁)進行解析提取出結構化的資料(有用資料)。比如,我們要抓取了一個新聞頁面的網頁(html)下來,但我們想要的是這個網頁中關于新聞的結構化資料:新聞的标題、新聞的釋出時間、新聞的正文等。

python爬蟲網頁解析器怎麼寫_Python 爬蟲網頁解析工具lxml.html(一)

是以說,網頁下載下傳下來隻是第一步,還有重要的一步就是資料提取。不同的爬蟲想要的資料不一樣,提取的資料也就不一樣,但提取方法都是類似的。

最簡單的提取資料的方法,就是使用正規表達式,此種方法簡單,提取的邏輯也不能複雜,不然寫出的正規表達式就晦澀難懂,甚至不能提取複雜的資料結構。

最終,老猿經過多年的使用經驗,選擇了lxml和xpath來解析網頁提取結構化資料。順便說一下 BeautifulSoup,它也是一個很棒的解析HTML的工具,可以使用多個解析器,比如Python标準庫的parser,但是速度比較慢,也可以使用lxml作為解析器,但是它的使用方法、API跟lxml不太一樣。使用下來,還是lxml的API更舒服。

lxml 對C語言庫 libxml2和 libxslt進行綁定,提供了Pythonic的API,它有一些主要特點:

支援标準的XML

支援(損壞)的HTML

非常快的解析速度

Pythonic的API更易于使用

使用Python的unicode字元串

記憶體安全(沒有段錯誤)

不需要手動管理記憶體

總結為一句話就是,C語言的速度和Python的簡易相結合的神器。

lxml有兩大部分,分别支援XML和HTML的解析:

lxml.etree 解析XML

lxml.html 解析html

lxml.etree可以用來解析RSS feed,它就是一個XML格式的文檔。然而爬蟲抓取的絕大部分都是html網頁,是以,我們這裡主要講述lxml.html解析網頁的方法。

lxml.html 從html字元串生成文檔樹結構

我們下載下傳得到的網頁就是一串html字元串,如何把它輸入給lxml.html子產品,進而生成html文檔的樹結構呢?

該子產品提供了幾種不同的方法:

parse(filename_url_or_file):

輸入的是一個檔案名、URL或檔案對象(有read()方法)。

document_fromstring(string):

輸入的是一個html的字元串,建立一個HTML文檔樹結構,它的根節點就是, 和 子節點。

fragment_fromstring(string, create_parent=False):

傳回輸入字元串的HTML片段。這個片段桌面隻含有一個element(元素),也就是單一節點,除非給出了create_parent 參數,否則會報錯。

fragments_fromstring(string):

傳回包含輸入字元串中所有片段的清單。

fromstring(string):

傳回值依據輸入字元串而定,如果輸入看起來像是一個文檔,則傳回document_fromstring(string),如果是一個單一片段,則傳回fragment_fromstring(string)。

下面我們通過具體示例來說明上面幾個方法的不同。

document_fromstring 的使用方法

In [1]: import lxml.html as lh

In [2]: z = lh.document_fromstring('abcxyz')

# 可以看到,它自動加了根節點

In [3]: z

Out[3]:

In [4]: z.tag

Out[4]: 'html'

# 還加了

節點

In [5]: z.getchildren()

Out[5]: []

# 把字元串的兩個節點放在了

裡面

In [6]: z.getchildren()[0].getchildren()

Out[6]: [, ]

fragment_fromstring 的使用

In [11]: z = lh.fragment_fromstring(‘

abc xyz ’)

---------------------------------------------------------------------------

ParserError Traceback (most recent call last)

in ()

----> 1 z = lh.fragment_fromstring(‘

abc xyz ’)

~/.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)

# 可以看到,輸入是兩個節點(element)時就會報錯

# 如果加上 create_parent 參數,就沒問題了

In [12]: z = lh.fragment_fromstring('

abc xyz ', create_parent='p')

In [13]: z.tag

Out[13]: 'p'

In [14]: z.getchildren()

Out[14]: [, ]

fragments_fromstring 的使用

# 輸入字元串含有一個節點,則傳回包含這一個節點的清單

In [17]: lh.fragments_fromstring('

abc ')

Out[17]: []

# 輸入字元串含有多個節點,則傳回包含這多個節點的清單

In [18]: lh.fragments_fromstring('

abc xyz ')

Out[18]: [, ]

fromstring 的使用

In [27]: z = lh.fromstring('

abc xyz ')

In [28]: z

Out[28]:

In [29]: z.getchildren()

Out[29]: [, ]

In [30]: type(z)

Out[30]: lxml.html.HtmlElement

這裡,fromstring輸入的如果是多個節點,它會給加一個父節點并傳回。但是像html網頁都是從節點開始的,我們使用fromstring() 和 document_fromstring() 都可以得到完整的網頁結構。

從上面代碼中我們可以看到,那幾個函數傳回的都是HtmlElement對象,也就是說,我們已經學會了如何從html字元串得到HtmlElement的對象,下一節我們将學習如何操作HtmlElement對象,從中提取我們感興趣的資料。

python爬蟲網頁解析器怎麼寫_Python 爬蟲網頁解析工具lxml.html(一)

我的公衆号:猿人學 Python 上會分享更多心得體會,敬請關注。

***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***