Python爬蟲 | 解析庫Xpath的使用

當爬取到Html數據後,能夠用正則對數據進行提取,但有時候正則表達式編寫起來不方便,並且萬一寫錯了,可能致使匹配失敗。這時候就須要藉助其餘解析工具了。

XML引入

什麼是XML?

  • XML 指可擴展標記語言(EXtensible Markup Language)
  • XML 是一種標記語言,很相似 HTML
  • XML 的設計宗旨是傳輸數據,而非顯示數據
  • XML 的標籤須要咱們自行定義。
  • XML 被設計爲具備自我描述性。
  • XML 是 W3C 的推薦標準

W3School官方文檔:http://www.w3school.com.cn/xm...html

XML和HTML的區別

語法要求不一樣node

  • 在html中不區分大小寫,在xml中嚴格區分。
  • 在HTML中,有時不嚴格,若是上下文清楚地顯示出段落或者列表鍵在何處結尾,那麼你能夠省略</p>或者</li>之類的結束標記。在XML中,是嚴格的樹狀結構,絕對不能省略掉結束標記。
  • 在XML中,擁有單個標記而沒有匹配的結束標記的元素必須用一個/ 字符做爲結尾。這樣分析器就知道不用查找結束標記了。
  • 在XML中,屬性值必須分裝在引號中。在HTML中,引號是可用可不用的。
  • 在HTML中,能夠擁有不帶值的屬性名。在XML中,全部的屬性都必須帶有相應的值。
  • 在XML文檔中,空白部分不會被解析器自動刪除;可是html是過濾掉空格的。

設計目標不一樣python

  • XML被設計爲傳輸和存儲數據,其焦點是數據的內容。
  • HTML顯示數據以及如何更好顯示數據。

XML的節點關係

一、父(parent)
每一個元素以及屬性都有一個父。
下面是一個簡單的XML例子中,book 元素是 title、author、year 以及 price 元素的父:git

<?xml version="1.0" encoding="utf-8"?>

<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

二、 子(Children)
元素節點可有零個、一個或多個子。
在下面的例子中,title、author、year 以及 price 元素都是 book 元素的子:github

<?xml version="1.0" encoding="utf-8"?>

<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

三、 同胞(Sibling)
擁有相同的父的節點
在下面的例子中,title、author、year 以及 price 元素都是同胞:正則表達式

<?xml version="1.0" encoding="utf-8"?>

<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

四、 先輩(Ancestor)
某節點的父、父的父,等等。
在下面的例子中,title 元素的先輩是 book 元素和 bookstore 元素:ubuntu

<?xml version="1.0" encoding="utf-8"?>

<bookstore>

<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

</bookstore>

五、 後代(Descendant)
某個節點的子,子的子,等等。
在下面的例子中,bookstore 的後代是 book、title、author、year 以及 price 元素:工具

<?xml version="1.0" encoding="utf-8"?>

<bookstore>

<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

</bookstore>

Xpath

什麼是Xpath?

Xpath,全稱XML Path Language,即XML路徑語言,它是一門在XML文檔中查找信息的語言,可用來在 XML 文檔中對元素和屬性進行遍歷。。最初是用來搜尋XML文檔的,可是它也適用與HTML文檔的搜索。
因此在作爬蟲時,可使用XPath來作相應的信息抽取。開發工具

W3School官方文檔:http://www.w3school.com.cn/xp...ui

Xpath開發工具

  1. 開源的XPath表達式編輯工具:XMLQuire(XML格式文件可用)
  2. Chrome插件 XPath Helper
  3. Firefox插件 XPath Checker

使用Xpath

XPath 使用路徑表達式來選取 XML 文檔中的節點或者節點集。這些路徑表達式和咱們在常規的電腦文件系統中看到的表達式很是類似。
一、Xpath經常使用規則

表達式 描述
nodename 選取此節點的全部子節點
/ 從當前節點選取直接子節點
// 從當前節點選取子孫節點
. 選取當前節點
.. 選取當前節點的父節點
@ 選取屬性

二、Xpath使用示例
如下面xmL文檔爲例:

<?xml version="1.0" encoding="utf-8"?>

<bookstore>

<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

</bookstore>
路徑表達式 結果
bookstore 選取bookstore元素的全部子節點
/bookstore 選取根元素bookstore。注:假如路徑起始於正斜槓/,則此路徑表明某元素的絕對路徑
bookstore/book 選取屬於bookstore的子元素的全部book元素
//book 選取全部book元素,無論在文檔的任何位置
bookstore//book 選擇屬於 bookstore 元素的後代的全部 book 元素,而無論它們位於 bookstore 之下的什麼位置。
//@lang 選取名爲lang的全部屬性

lxml庫使用

lxml庫安裝

一、window安裝
cmd進入命令行模式,執行

pip3 install lxml

二、ubuntu16.04安裝
ctrl+alt+t進入終端模式,執行:

sudo apt-get install -y build-essential libssl-devl libffi-dev libxml2-dev libxslt1-dev zlib1g-dev

安裝依賴的類庫後,執行pip安裝:

sudo pip3 install lxml

三、驗證安裝
導入lxml模塊,若是沒有報錯就安裝成功。

$ python3
>>> import lxml

etree模塊使用

初步使用
文件名lxml_test.py

# 使用 lxml 的 etree 庫
from lxml import etree 

text = '''
<div>
    <ul>
         <li class="item-0"><a href="link1.html">first item</a></li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-inactive"><a href="link3.html">third item</a></li>
         <li class="item-1"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a> # 注意,此處缺乏一個 </li> 閉合標籤
     </ul>
 </div>
'''

#利用etree.HTML,將字符串解析爲HTML文檔,etree模塊可自動修正HTML文本
html = etree.HTML(text) 

# 按字符串序列化HTML文檔
ret = etree.tostring(html) 

# torstring()方法返回的結果是bytes類型,這裏用decode()方法將其轉化爲字符串
print(ret.decode('utf-8'))

輸出結果:

<html><body>
<div>
    <ul>
         <li class="item-0"><a href="link1.html">first item</a></li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-inactive"><a href="link3.html">third item</a></li>
         <li class="item-1"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
 </div>
</body></html>

etree模塊能夠自動修正 html 代碼,例子裏不只補全了 li 標籤,還添加了 body,html 標籤。

文件讀取
除了直接讀取字符串,lxml還支持從文件裏讀取內容。這裏我將上面的lxml_test.py文件執行後的內容保存爲test.html

python lxml_test.py >> test.html

內容就是上面的輸出結果 cat test.html:

<div>
    <ul>
         <li class="item-0"><a href="link1.html">first item</a></li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     </ul>
 </div>

使用etree.parse()方法來讀取文件。

from lxml import etree

html = etree.parse('./test.html',HTMLParser())

ret = etree.tostring(html)
print(ret.decode('utf-8'))

輸出結果

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<div>
    <ul>
         <li class="item-0"><a href="link1.html">first item</a></li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-inactive"><a href="link3.html">third item</a></li>
         <li class="item-1"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
 </div>
</body></html>

輸出結果多了一個DOCTYPE聲明,對解析結果沒影響。

相關文章
相關標籤/搜索