python_Xpath入门


一:什么是XPath

  XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。

  XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。   XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。起初XPath的提出的初衷是将其作为一个通用的、介于XPointer与XSL间的语法模型。但是XPath很快地被开发者采用来当作小型查询语言。  

二:语法

选取节点 XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。 [1]表达式以及表达式的结果:
路径表达式 结果
bookstore 选取 bookstore 元素的所有子节点。
/bookstore 选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。
//book 选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang 选取名为 lang 的所有属性。

  案例:(博客:https://www.cnblogs.com/lei0213/p/7506130.html)

from lxml import etree
 
wb_data = """
        
        """
html = etree.HTML(wb_data)
print(html)
result = etree.tostring(html)
print(result.decode("utf-8"))

#从输出结果来看,我们打印机html其实就是一个python对象,#etree.tostring(html)则是不全里html的基本写法,补全了缺胳膊少腿的#标签(html,body)

#获取某个标签的内容(基本使用) 使用了text()函数 后面有提到

html = etree.HTML(wb_data)
html_data = html.xpath('/html/body/div/ul/li/a/text()')  
print(html)
for i in html_data:
    print(i)

#打印指定路径下a标签的属性(可以通过遍历拿到某个属性的值,查找标签的内容)
html = etree.HTML(wb_data)
html_data = html.xpath('/html/body/div/ul/li/a/@href')
for i in html_data:
    print(i)

谓语

谓语用来查找某个特定的节点或者包含某个指定的值的节点。

谓语被嵌在方括号中。

在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

路径表达式结果
/bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang='eng'] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]//title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

选取未知节点

XPath 通配符可用来选取未知的 XML 元素。

通配符描述
* 匹配任何元素节点。
@* 匹配任何属性节点。
node() 匹配任何类型的节点。

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式结果
/bookstore/* 选取 bookstore 元素的所有子元素。
//* 选取文档中的所有元素。
//title[@*] 选取所有带有属性的 title 元素。

选取若干路径

通过在路径表达式中使用"|"运算符,您可以选取若干个路径。

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式结果
//book/title | //book/price 选取 book 元素的所有 title 和 price 元素。
//title | //price 选取文档中的所有 title 和 price 元素。
/bookstore/book/title | //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。

 

三:运算符


xpath内置很多函数。更多函数查看https://www.w3school.com.cn/xpath/xpath_functions.asp

  • contains(string1,string2)
  • starts-with(string1,string2)
  • ends-with(string1,string2) #不支持
  • upper-case(string) #不支持
  • text()
  • last()
  • position()
  • node()

自定义函数

我们从使用函数的过程中得到结论,就是有的函数不支持,有的支持,那问题来了,到底哪些函数支持呢。我们在lxml官网找到了答案。https://lxml.de/xpathxslt.html。lxml 支持XPath 1.0 ,想使用其他扩展,使用libxml2,和libxslt的标准兼容的方式。XPath 1.0官方文档 以及其他版本的XPath文档 https://www.w3.org/TR/xpath/

lxml supports XPath 1.0, XSLT 1.0 and the EXSLT extensions through libxml2 and libxslt in a standards compliant way. 

除此之外,lxml还提供了自定义函数的方式来扩展xpath的支持度 https://lxml.de/extensions.html

节点关系(百度百科)

编辑 播报 节点(Node)是XPath 的术语。 在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。 [2]  父(Parent) 每个元素以及属性都有一个父。 在下面的例子中,book 元素是 title、author、year 以及 price 元素的父:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <book>     <title>HarryPottertitle>     <author>JK.Rowlingauthor>     <year>2005year>     <price>29.99price>     book>
子(Children) 元素节点可有零个、一个或多个子。 在下面的例子中,title、author、year 以及 price 元素都是 book 元素的子:
1 2 3 4 5 6 <book> <title>HarryPottertitle> <author>JK.Rowlingauthor> <year>2005year> <price>29.99price> book>
同胞(Sibling) 拥有相同的父的节点 在下面的例子中,title、author、year 以及 price 元素都是同胞:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <book>     <title>HarryPottertitle>     <author>JK.Rowlingauthor>     <year>2005year>     <price>29.99price>     book>
先辈(Ancestor) 某节点的父、父的父,等等。 在下面的例子中,title 元素的先辈是 book 元素和 bookstore 元素:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <bookstore>         <book>     <title>HarryPottertitle>     <author>JK.Rowlingauthor>     <year>2005year>     <price>29.99price>     book>         bookstore>
后代(Descendant) 某个节点的子,子的子,等等。 在下面的例子中,bookstore 的后代是 book、title、author、year 以及 price 元素:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <bookstore>         <book>     <title>HarryPottertitle>     <author>JK.Rowlingauthor>     <year>2005year>     <price>29.99price>     book>         bookstore>
 

存取函数(百度)

编辑 播报 名称 说明 fn:node-name(node) 返回参数节点的节点名称。 fn:nilled(node) 返回是否拒绝参数节点的布尔值。 fn:data(item.item,...) 接受项目序列,并返回原子值序列。 fn:base-uri() fn:base-uri(node) 返回当前节点或指定节点的 base-uri 属性的值。 fn:document-uri(node) 返回指定节点的 document-uri 属性的值。