這篇文章將為大家詳細(xì)講解有關(guān)爬蟲網(wǎng)頁內(nèi)容提取神器之xpath是什么,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
成都創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的廣昌網(wǎng)站設(shè)計(jì)、移動媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
XPath 是什么?
XPath的全稱是 XML Path Language,即XML 路徑語言,是一種在XML(HTML)文檔中查找信息的語言。它有4點(diǎn)特性:
XPath 使用路徑表達(dá)式在 XML 文檔中進(jìn)行導(dǎo)航
XPath 包含一個(gè)標(biāo)準(zhǔn)函數(shù)庫
XPath 是 XSLT 中的主要元素
XPath 是一個(gè) W3C 標(biāo)準(zhǔn)我們從網(wǎng)頁中提取數(shù)據(jù),主要應(yīng)用前兩點(diǎn)。
XPath 路徑表達(dá)式
使用XPath我們可以很容易定位到網(wǎng)頁中的節(jié)點(diǎn),也就是找到我們關(guān)心的數(shù)據(jù)。這些路徑跟電腦目錄、網(wǎng)址的路徑很相似,通過/來表示路徑的深度。
XPath 標(biāo)注函數(shù)庫
頭內(nèi)建了100多個(gè)函數(shù),當(dāng)然我們提取數(shù)據(jù)用到的有限,也就不用記住全部100多個(gè)函數(shù)了。
Xpath 的節(jié)點(diǎn)(Node)
XPath中的核心就是節(jié)點(diǎn)(Node),定義了7種不同類型的節(jié)點(diǎn): 元素(Element)、屬性(Attribute)、文本(Text)、命名空間(Namespace)、處理指令(processing-instruction)、注釋(Comment)和文檔節(jié)點(diǎn)(Document nodes)
這些節(jié)點(diǎn)組成一棵節(jié)點(diǎn)樹,樹的根節(jié)點(diǎn)被稱為文檔節(jié)點(diǎn)。
其中注釋就是html里面的注釋:
而命名空間、處理指令和網(wǎng)頁數(shù)據(jù)提取基本沒關(guān)系,這里就不再詳述。
下面我們以一個(gè)簡單的html文檔為例,來解釋不同的節(jié)點(diǎn)及其關(guān)系。
ABC
這段html中的節(jié)點(diǎn)有:
文檔節(jié)點(diǎn):
元素節(jié)點(diǎn):
屬性節(jié)點(diǎn): id="menu"
XPath 節(jié)點(diǎn)的關(guān)系
節(jié)點(diǎn)間的關(guān)系完全照搬人類傳宗接代的輩分關(guān)系,但只是直系關(guān)系,沒有叔叔、大伯之類的旁系關(guān)系。
還是以上面的html文檔為例來說明節(jié)點(diǎn)關(guān)系:
父(Parent)
每個(gè)元素節(jié)點(diǎn)(Element)及其屬性都有一個(gè)父節(jié)點(diǎn)。
比如,body的父是html,而body是div、ul 的父親。
子(Children)
每個(gè)元素節(jié)點(diǎn)可以有零個(gè)、一個(gè)或多個(gè)子。
比如,body有兩個(gè)子:div,ul,而ul也有兩個(gè)子:兩個(gè)li。
同輩(Sibling)
同輩有相同的父輩節(jié)點(diǎn)。
比如,div和ul是同輩。
先輩(Ancestor)
某節(jié)點(diǎn)的父輩及其以上輩分的節(jié)點(diǎn)。
比如,li的父輩有:ul、div、body、html
后代(Descendant)
某節(jié)點(diǎn)的子及其子孫節(jié)點(diǎn)。
比如,body的后代有:div、ul、li。
XPath節(jié)點(diǎn)的選取
選取節(jié)點(diǎn),也就是通過路徑表達(dá)來實(shí)現(xiàn)。這是我們在網(wǎng)頁提取數(shù)據(jù)時(shí)的關(guān)鍵,要熟練掌握。
下表是比較有用的路徑表達(dá)式:
表達(dá)式 | 說明 |
---|---|
nodename | 選取當(dāng)前節(jié)點(diǎn)的名為nodename的所有子節(jié)點(diǎn)。 |
/ | 從根節(jié)點(diǎn)選取,在路徑中間時(shí)表示一級路徑 |
// | 從當(dāng)前節(jié)點(diǎn)開始選擇文檔中的節(jié)點(diǎn),可以是多級路徑 |
. | 從當(dāng)前節(jié)點(diǎn)開始選取 |
.. | 從父節(jié)點(diǎn)開始選取 |
@ | 按屬性選取 |
接下來通過具體的示例來加深對路徑表達(dá)的理解:
路徑表達(dá)式 | 解釋 |
---|---|
/html/body/ul/li | 從根節(jié)點(diǎn)開始依照路徑選取li元素。返回多個(gè)。 |
//ul/li[1] | 還是選取li元素,但是路徑多級跳躍到ul/li。[1]表示只取第一個(gè)li。 |
//li[last()] | 還是選取li,但路徑更跳躍。[last()]表示取最后一個(gè)li元素。 |
//li[@class] | 選取根節(jié)點(diǎn)的名為li且有class屬性的所有后代。 |
//li[@class=”item”] | 選擇根節(jié)點(diǎn)的名為li且class屬性為item的所有后代。 |
//body/*/li | 選取body的名為li的孫子節(jié)點(diǎn)。* 是通配符,表示任何節(jié)點(diǎn)。 |
//li[@*] | 選取所有帶屬性的li元素。 |
//body/div | //body/ul | 選取body的所有div和ul元素。 |
body/div | 相對路徑,選取當(dāng)前節(jié)點(diǎn)的body元素的子元素div。絕對路徑以 / 開始。 |
XPath函數(shù)
Xpath的函數(shù)很多,涉及到錯誤、數(shù)值、字符串、時(shí)間等等,然而我們從網(wǎng)頁中提取數(shù)據(jù)的時(shí)候只會用到很少的一部分。其中最重要的就是字符串相關(guān)的函數(shù),比如contains()函數(shù)。
contains(a, b)
如果字符串a(chǎn)包含字符串b,則返回true,否則返回false。
比如: contains(‘猿人學(xué)Python’, ‘Python’),返回true
那么它用在什么時(shí)候呢?我們知道,一個(gè)html標(biāo)簽的class是可以有多個(gè)屬性值的,比如:
...
這段html中div有三個(gè)class值,第一個(gè)表面它是一條發(fā)布的消息,后面兩個(gè)是對格式做了更多的設(shè)置。如果我們想提取網(wǎng)頁中所有發(fā)布的消息,只需要匹配到post-item 即可,這時(shí)候就可以用上contains了:
doc.xpath('//div[contains(@class, "post-item")]')
跟contains()類似的字符串匹配的函數(shù)還有:
starts-with(string1, string2) 判斷string1是否以string2開頭ends-with(string1, string2) 判斷string1是否以string2結(jié)尾matches(string, pattern) 通過正則表達(dá)式匹配
然而,在lxml的xpath中使用ends-with(), matches() 會報(bào)錯
In [232]: doc.xpath('//ul[ends-with(@id, "u")]') --------------------------------------------------------------------------- XPathEvalError Traceback (most recent call last)in () ----> 1 doc.xpath('//ul[ends-with(@id, "u")]') src/lxml/etree.pyx in lxml.etree._Element.xpath() src/lxml/xpath.pxi in lxml.etree.XPathElementEvaluator.__call__() src/lxml/xpath.pxi in lxml.etree._XPathEvaluatorBase._handle_result() XPathEvalError: Unregistered function
lxml 竟然不支持ends-with(), matches()函數(shù)
到lxml官方網(wǎng)站去看看,原來它說了只支持 XPath 1.0:
lxml supports XPath 1.0, XSLT 1.0 and the EXSLT extensions through libxml2 and libxslt in a standards compliant way.
關(guān)于爬蟲網(wǎng)頁內(nèi)容提取神器之xpath是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。