python Xpath語法的使用
一、XMl簡介
(一)什么是 XML
XML 指可擴(kuò)展標(biāo)記語言(EXtensible)XML 是一種標(biāo)記語言,很類似 HTML。XML 的設(shè)計(jì)宗旨是傳輸數(shù)據(jù),而非顯示數(shù)據(jù)。XML 的標(biāo)簽需要我們自行定義。XML 被設(shè)計(jì)為具有自我描述性。XML 是 W3C 的推薦標(biāo)準(zhǔn)。W3School 官方文檔:http://www.w3school.com.cn/xml/index.asp
(二)XML 和 HTML 的區(qū)別
他們兩者都是用于操作數(shù)據(jù)或者結(jié)構(gòu)數(shù)據(jù),在結(jié)構(gòu)上大致相同的,但他們?cè)诒举|(zhì)上卻存在著明顯的區(qū)別。
數(shù)據(jù)格式 描述 設(shè)計(jì)目標(biāo) XML Extensible Markup Language ( 可擴(kuò)展標(biāo)記語言) 被設(shè)計(jì)為傳輸和存儲(chǔ)數(shù)據(jù),其焦點(diǎn)是數(shù)據(jù)的內(nèi)容。 HTML HyperText Markup Language(超文本標(biāo)記語言) 顯示數(shù)據(jù)以及如何更好顯示數(shù)據(jù)。 HTML DOM Document Object Model for HTML(超文本標(biāo)文檔對(duì)象模型) 通過 HTML DOM,可以訪問所有的 HTML 元素, 連同它們所包含的文本和屬性。可以對(duì)其中的內(nèi)容進(jìn)行修改和刪除,同時(shí)也可以創(chuàng)建新的元素。
(三)XML 的節(jié)點(diǎn)關(guān)系
<?XML version=’1.0’ encoding=''utf-8><book category='cooking'> <title lang='en'>Harry Potter</title> <author>J K.Rowling</author> <year>2005</year> <price>29.00</price></book>
1.父(Parent)每個(gè)元素以及屬性都有一個(gè)父。上面是一個(gè)簡單的 XML 例子中,book 元素是 title、author、year 以及 price 元素的父
2.子(Children)元素節(jié)點(diǎn)可有零個(gè)、一個(gè)或多個(gè)子元素。在上面的例子中,title、author、year 以及 price 元素都是 book 元素的子元素
3. 同胞(Sibling)擁有相同的父的節(jié)點(diǎn)。在上面的例子中,title、author、year 以及 price 元素都是同胞
4. 先輩(Ancestor)某節(jié)點(diǎn)的父、父的父,等等。在上面的例子中,title 元素的先輩是 book 元素和 bookstore元素
5. 后代(Descendant)某個(gè)節(jié)點(diǎn)的子,子的子等等。在上面的例子中,bookstore 的后代是 book、title、author、year 以及 price 元素:
二、XPATH
XPath (XML Path Language) 是一門在 XML 文檔中查找信息的語言,可用來在 XML 文檔中對(duì)元素和屬性進(jìn)行遍歷。
(一)選取節(jié)點(diǎn)
XPath 使用路徑表達(dá)式來選取 XML 文檔中的節(jié)點(diǎn)或者節(jié)點(diǎn)集。這些路徑表達(dá)式和我們?cè)诔R?guī)的電腦文件系統(tǒng)中看到的表達(dá)式非常相似。下面列出了最常用的路徑表達(dá)式:
表達(dá)式 描述 nodename 選取此節(jié)點(diǎn)的所有子節(jié)點(diǎn)。 / 從節(jié)點(diǎn)選取。 // 從匹配選擇的當(dāng)前節(jié)點(diǎn)選擇文檔中的節(jié)點(diǎn),而不考慮他們的位置。 . 選取當(dāng)前節(jié)點(diǎn)。 .. 選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)。 @ 選取屬性。
在下面的表格中,我們已列出了一些路徑表達(dá)式以及表達(dá)式的結(jié)果:
路徑表達(dá)式 描述 bookstore 選取 bookstore 元素的所有子節(jié)點(diǎn) /bookstore 選取根元素 bookstore。代表元素的絕對(duì)路徑。 bookstore/book 選取屬于 bookstore 的子元素的所有 book 元素。 //book 選取所有 book 子元素,而不管它們?cè)谖臋n中的位置 bookstore//book 選擇屬于 booksore 元素的后代所有的 book 元素,而不管他們位于 bookstore 之下的什么位置。 //@lang 選取名為 lang 的所有屬性。 text() 取標(biāo)簽當(dāng)中的值
(二)謂語(Predicates)
謂語用來查找某個(gè)特定的節(jié)點(diǎn)或者包含某個(gè)指定的值的節(jié)點(diǎn),被嵌在方括號(hào)中。在下面的表格中,我們列出了帶有謂語的一些路徑表達(dá)式,以及表達(dá)式的結(jié)果:
路徑表達(dá)式 描述 /bookstore/book[l] 選取屬于 bookstore 子元素的第一個(gè) book 元素。 /bookstore/book[last()] 選取屬于 bookstore 子元素的最后一個(gè) book 元素。 /bookstore/book[last()-1] 選取屬于 bookstore 子元素的倒數(shù)第二個(gè) book 元素。 /bookstore/book[position()<2] 選最前面的一個(gè)屬于 bookstore 元素的子元素的 book 元素。 //title[@lang] 選取所有屬性名為 lang 的屬性的 title 元素。 //titlel@lang=‘eng’] 選取所有 tltle 元素,且這些元素有屬性值為 eng 的 lang 屬性。
(三)選取未知節(jié)點(diǎn)
XPath 通配符可用來選取未知的 XML 元素。
通配符 描述 * 匹配任何元素節(jié)點(diǎn)。 @* 匹配任何屬性節(jié)點(diǎn)。
在下面的表格中,我們列出了一些路徑表達(dá)式,以及這些表達(dá)式的結(jié)果:
路徑表達(dá)式 描述 /bookstore/* 選取 bookstore 元素的所有子元素 //* 選取文檔中的所有元素。 //title[@*] 選取所有帶有屬性的 title 元素。
(四)選取若干路徑
通過在路徑表達(dá)式中使用“|”運(yùn)算符,您可以選取若干個(gè)路徑。在下面的表格中,我們列出了一些路徑表達(dá)式,以及這些表達(dá)式的結(jié)果:
路徑表達(dá)式 描述 //book/title //book/price //title //price //price 選取文檔中所有的 price 元素。
三、lxml 模塊
(一)lxml 簡介與安裝lxml 是一個(gè) HTML/XML 的解析器,主要的功能是如何解析和提取 HTML/XML 數(shù)據(jù)。我們可以利用之前學(xué)習(xí)的 XPath 語法,來快速的定位特定元素以及節(jié)點(diǎn)信息。安裝方法:pip install lxml
(二)lxml 初步使用
1、解析HTML字符串
from lxml import etreetext = '''<div> <ul> <li class='item-0'><a href='http://www.cgvv.com.cn/bcjs/link1.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >first item</a></li> <li class='item-1'><a href='http://www.cgvv.com.cn/bcjs/link2.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >second item</a></li> <li class='item-inactive'><a href='http://www.cgvv.com.cn/bcjs/link3.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >third item</a></li> <li class='item-1'><a href='http://www.cgvv.com.cn/bcjs/link4.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >fourth item</a></li> <li class='item-0'><a href='http://www.cgvv.com.cn/bcjs/link5.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >fifth item</a> </ul></div>'''html = etree.HTML(text)result = etree.tostring(html,pretty_print=True).decode(’utf-8’)print(result)from lxml import etreetext = '''<div> <ul> <li class='item-0'><a href='http://www.cgvv.com.cn/bcjs/link1.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >first item</a></li> <li class='item-1'><a href='http://www.cgvv.com.cn/bcjs/link2.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >second item</a></li> <li class='item-inactive'><a href='http://www.cgvv.com.cn/bcjs/link3.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' ><span class='bold'>third item</span>></a></li> <li class='item-1'><a href='http://www.cgvv.com.cn/bcjs/link4.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >fourth item</a></li> <li class='item-0'><a href='http://www.cgvv.com.cn/bcjs/link5.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >fifth item</a></li> </ul></div>'''# 初始化一個(gè)Xpath解析對(duì)象html = etree.HTML(text)# 解析對(duì)象輸出代碼 是一個(gè)bytes類型result = etree.tostring(html,encoding=’utf-8’)print(type(html)) # <class ’lxml.etree._Element’>print(type(result)) # <class ’bytes’>print(result.decode(’utf-8’))
小結(jié):lxml 可以自動(dòng)修正 html 代碼,例子里不僅補(bǔ)全了 li 標(biāo)簽,還添加了 body,html 標(biāo)簽。
2.、lxml 文件讀取
from lxml import etreetext = '''<div> <ul> <li class='item-0'><a href='http://www.cgvv.com.cn/bcjs/link1.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >first item</a></li> <li class='item-1'><a href='http://www.cgvv.com.cn/bcjs/link2.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >second item</a></li> <li class='item-inactive'><a href='http://www.cgvv.com.cn/bcjs/link3.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' ><span class='bold'>third item</span>></a></li> <li class='item-1'><a href='http://www.cgvv.com.cn/bcjs/link4.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >fourth item</a></li> <li class='item-0'><a href='http://www.cgvv.com.cn/bcjs/link5.html' rel='external nofollow' rel='external nofollow' rel='external nofollow' >fifth item</a></li> </ul></div>'''# 初始化一個(gè)Xpath解析對(duì)象html = etree.HTML(text)# 解析對(duì)象輸出代碼 是一個(gè)bytes類型result = etree.tostring(html,encoding=’utf-8’)print(type(html)) # <class ’lxml.etree._Element’>print(type(result)) # <class ’bytes’>print(result.decode(’utf-8’))
除了直接讀取字符串,lxml 還支持從文件里讀取內(nèi)容。我們新建一個(gè) hello.html 文件,再利用 etree.parse()方法來讀取文件。注意:從文件中讀取數(shù)據(jù),要求文件內(nèi)容符合 xml 格式,如果標(biāo)簽缺失,則不能正常讀取。
四、XPath 節(jié)點(diǎn)信息解析:
# 安裝lxml: pip install lxml# 1. 導(dǎo)入etree: 兩種導(dǎo)入方式# 第一種: 直接導(dǎo)入from lxml import etree# 注意: 此種導(dǎo)入方式,可能會(huì)導(dǎo)致報(bào)錯(cuò)(etree下面會(huì)出現(xiàn)紅色波浪線,不影響正常使用)# 第二種: # from lxml import html# etree = html.etreestr = ’<bookstore>’ ’<book>’ ’<title lang='bng' src='https://www.baidu.com'>Harry Potter</title>’ ’<price>29.99</price>’ ’</book>’ ’<book>’ ’<title lang='ang'>Learning XML</title>’ ’<price>39.95</price>’ ’</book>’ ’<book>’ ’<title lang='cng'>西游記</title>’ ’<price>69.95</price>’ ’</book>’ ’<book>’ ’<title lang='dng' src='https://www.jd.com'>水滸傳</title>’ ’<price>29.95</price>’ ’</book>’ ’<book>’ ’<title lang='dng' src='https://www.jd.com'>三國演義</title>’ ’<price>29.95</price>’ ’</book>’ ’</bookstore>’# 2. etree.HTML() 將字符串轉(zhuǎn)換成HTML元素對(duì)象,可以自動(dòng)添加缺失的元素html = etree.HTML(str) # <Element html at 0x1e17b839708> 是一個(gè)el對(duì)象# print(html)# 3. 方法:# 3.1 tostring() 查看轉(zhuǎn)換之后的內(nèi)容(二進(jìn)制類型)# 如果想要查看字符串,需要解碼# 如果想要顯示漢字,需要先編碼,再解碼# content = etree.tostring(html,encoding=’utf-8’)# print(content.decode())# 3.2 xpath()方法 作用:提取頁面數(shù)據(jù),返回值是一個(gè)列表# xpath的使用一定是建立在etree.HTML()之后的內(nèi)容中的# xpath是如何來提取頁面數(shù)據(jù)的?# 答:使用的是路徑表達(dá)式# 3.2.1 xpath路徑分為兩種:# 第一種: / 代表一層層的查找,如果/存在于開頭,代表根路徑# bookstore = html.xpath(’/html/body/bookstore’)# print(bookstore) # [<Element bookstore at 0x2dd535efb88>]# 第二種: // 任意路徑 焦點(diǎn)在元素身上# 例如:查找bookstore標(biāo)簽# bookstore = html.xpath(’//bookstore’)# print(bookstore) # [<Element bookstore at 0x1639054fdc8>]# 第一種和第二種結(jié)合# 例如:查找所有book標(biāo)簽# book = html.xpath(’//bookstore/book’)# print(book) # [<Element book at 0x2737fd7fa48>, <Element book at 0x2737fd7fc88>, <Element book at 0x2737fd7fcc8>, <Element book at 0x2737fd7fd08>, <Element book at 0x2737fd7fd88>]# 3.2.2 /text() 獲取標(biāo)簽之間的內(nèi)容# 例如:獲取所有title標(biāo)簽的內(nèi)容# 步驟:# 1. 找到所有title標(biāo)簽# 2. 獲取內(nèi)容# title = html.xpath(’//book/title/text()’)# print(title) # [’Harry Potter’, ’Learning XML’, ’西游記’, ’水滸傳’, ’三國演義’]# 3.3 位于 使用[] 可以理解成條件# 3.3.1 [n] 代表獲取第n個(gè)元素,n是數(shù)字,n<=1# 例如: 獲取第二個(gè)title標(biāo)簽# title = html.xpath(’//book[2]/title/text()’)# title1 = html.xpath(’//title[2]/text()’)# print(title) # [’Learning XML’]# print(title1) # []# last() 獲取最后一個(gè)# 同理: last()-1 獲取倒數(shù)第二個(gè)# 例如: 獲取最后一本書的title標(biāo)簽之間的內(nèi)容# title = html.xpath(’//book[last()]/title/text()’)# title1 = html.xpath(’//book[last()-1]/title/text()’)# print(title) # [’三國演義’]# print(title1) # [’水滸傳’]# 3.3.2 position() 位置,范圍 支持 > / < / = / >= / <= / !=# 例如: 獲取最后兩本書的title標(biāo)簽之間的內(nèi)容# 步驟:# 1. 先獲取后兩本書# 2. 獲取內(nèi)容# title = html.xpath(’//book[position()>3]/title/text()’)# print(title) # [’水滸傳’, ’三國演義’]# ? title = html.xpath(’//book[position()>last()-2]/title/text()’)# print(title) # [’水滸傳’, ’三國演義’]# 3.3.3 獲取屬性值:@屬性名# 例如: 獲取lang屬性值為cng的title標(biāo)簽的內(nèi)容# title = html.xpath(’//book/title[@lang='cng']/text()’)# print(title) # [’西游記’]# 例如: 獲取包含src屬性得title標(biāo)簽的內(nèi)容# title = html.xpath(’//book/title[@src]/text()’)# print(title) # [’Harry Potter’, ’水滸傳’, ’三國演義’]# 例如: 獲取包含屬性的title標(biāo)簽的內(nèi)容# title = html.xpath(’//book/title[@*]/text()’)# print(title) # [’Harry Potter’, ’Learning XML’, ’西游記’, ’水滸傳’, ’三國演義’]# 例如: 獲取最后一個(gè)title標(biāo)簽的src屬性的值# title = html.xpath(’//book[last()]/title/@src’)# print(title) # [’https://www.jd.com’]# 例如: 獲取所有包含src屬性的標(biāo)簽之間的內(nèi)容# node = html.xpath(’//*[@src]/text()’)# print(node) # [’Harry Potter’, ’水滸傳’, ’三國演義’]# 3.4 and 與 連接的是謂語(條件)# 例如: 獲取lang='dng'并且class='t1'的title標(biāo)簽的內(nèi)容# title = html.xpath(’//book/title[@lang='dng' and @class='t1']/text()’)# title1 = html.xpath(’//book/title[@lang='dng'][@class='t1']/text()’)# print(title) # [’三國演義’]# print(title1) # [’三國演義’]# 3.5 or 或 連接謂語# 例如: 查找lang='cng'或者lang='bng'的title標(biāo)簽的內(nèi)容# title = html.xpath(’//book/title[@lang='cng' or @lang='bng']/text()’)# print(title) # [’Harry Potter’, ’西游記’]# 3.6 | 連接路徑# 例如: 獲取所有title標(biāo)簽和price標(biāo)簽之間的內(nèi)容# title = html.xpath(’//title/text() | //price/text()’)# print(title) # [’Harry Potter’, ’29.99’, ’Learning XML’, ’39.95’, ’西游記’, ’69.95’, ’水滸傳’, ’29.95’, ’三國演義’, ’29.95’]# 3.8 parse() 作用:從文件中讀取數(shù)據(jù)# 注意: 讀取的文件,必須滿足xml格式**(不存在單標(biāo)簽,全部都是上標(biāo)簽)**content = etree.parse(’test.html’)# print(content) # <lxml.etree._ElementTree object at 0x000001DC5CF5ED08>res = etree.tostring(content,encoding=’utf-8’)print(res.decode()) <!DOCTYPE html><html lang='en'><head> <title>test</title></head><body> <h1> 這是一個(gè)html </h1></body></html>
到此這篇關(guān)于python Xpath語法的使用的文章就介紹到這了,更多相關(guān)python Xpath語法內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. Python如何批量生成和調(diào)用變量2. ASP.NET MVC實(shí)現(xiàn)橫向展示購物車3. ASP.Net Core對(duì)USB攝像頭進(jìn)行截圖4. .net如何優(yōu)雅的使用EFCore實(shí)例詳解5. ASP.Net Core(C#)創(chuàng)建Web站點(diǎn)的實(shí)現(xiàn)6. python 爬取京東指定商品評(píng)論并進(jìn)行情感分析7. python基礎(chǔ)之匿名函數(shù)詳解8. Python獲取B站粉絲數(shù)的示例代碼9. ajax動(dòng)態(tài)加載json數(shù)據(jù)并詳細(xì)解析10. 通過CSS數(shù)學(xué)函數(shù)實(shí)現(xiàn)動(dòng)畫特效
