python学习笔记 | xpath

关于lxml

python-xml-title

​ lxml是python的一个解析库,支持「HTML」和「XML」的解析,支持xpath解析方式,而且解析效率非常高。

1. 安装

  • Windows/macOS

    pip3 install lxml
    
  • Linux

    yum install -y epel-release libxslt-devel libxml2-devel openssl-devel
    pip3 install lxml
    

2. 导入

from lxml import etree

3. 解析为文档树

etree.parse(source, parser=None, base_url=None) - Return an ElementTree object loaded with source elements.

  • source - 文件名\路径、文件对象、url
  • parser - 例:etree.XMLParser()etree.HTMLParser()等,如不设置则使用默认的parser
  • base_url -

etree.XML(text, parser=None, base_url=None) - Parses an XML document or fragment from a string constant.

  • text - byte类型
  • parser -
  • base_url -

etree.HTML(text, parser=None, base_url=None) - Parses an HTML document from a string constant. Returns the root node (or the result returned by a parser target).

  • text -
  • parser -
  • base_url -

etree.fromstring(text, parser=None, base_url=None) - Parses an XML document or fragment from a string.

4. 文档树的一些方法

etree.tostring(element_or_tree, encoding=None, ...) - 解析成字节

etree.tostringlist(element_or_tree, ...) - 解析成列表

关于xpath

xpath(已去底)

XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索。

XPath的选择功能十分强大,它提供了非常简明的路径选择表达式,另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等,几乎所有我们想要定位的节点,都可以用XPath来选择。

XPath于1999年11月16日成为W3C标准,它被设计为供XSLT、XPointer以及其他XML解析软件使用,更多的文档可以访问其官方网站:https://www.w3.org/TR/xpath/

  • XPath 使用路径表达式在 XML 文档中进行导航
  • XPath 包含一个标准函数库
  • XPath 是 XSLT 中的主要元素
  • XPath 是一个 W3C 标准

推荐阅读

1. xpath方法

lxml.etree._ElementTree.xpath(_path) - 使用lxml提供的这个方法可以对文档树对象进行解析,从而获取节点信息,此方法返回结果的类型均为「list

eleTree = etree.HTML(text)
html = eleTree.xpath(' ') # ' '中的规则如下

2. xpath选取节点

表达式 描述
nodename 选取此节点的所有子节点
/ 根节点
// 从匹配的当前节点选择后代中所有符合的节点,而不考虑它们的位置
. 当前节点
.. 当前节点的父节点
@ 属性
[] 条件检索
* 通配符,表示该路径下的所有元素,例//*(选择所有元素),@*匹配任何属性的节点

3. xpath运算符

运算符 描述 实例
| 多个路径选择的并集 `//p
+ 加法
- 减法
* 乘法
div 除法
= 等于
!= 不等于
< 小于
<= 小于或等于
> 大于 //div/li[position() > 3]
>= 大于或等于
or
and //div[contains(@id,"test") and contains(@id,"title")]
mod 计算除法的余数

4. xpath谓语(Predicates)

被嵌在方括号[]中的条件语句,可以理解为xpath语法中的谓语,用来查找符合条件的「某个特定的节点或者包含某个指定的值的节点」。

表达式 描述
[ ] 条件检索
//div/li[1] 选取div节点下第一个li节点
//div/li[last()] 选取div节点下最后一个li节点
//div/li[position()<3] 选取div节点下前两个li节点
//div/li[@GOD] 选取div节点下所有拥有GOD属性的li节点

5. xpath谓语函数

XPath的选择功能十分强大,它提供了非常简明的路径选择表达式,另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等,几乎所有我们想要定位的节点,都可以用XPath来选择。 XPath 函数改进 了XPath 查询,并提高 XPath 的编程能力和灵活性。

推荐阅读 - XPath、XQuery 以及 XSLT 函数函数参考手册

  • text()

    xpath('//div/text()') # 功能强大,是我觉得最powerful的一个功能
    xpath('//div[text() = "黄卡特"]') # 条件检索
    
  • contains() - 包含指定的元素

    xpath('//div/ul/li[contains(text(),"列表1")]') # 等同于上面的用法2
    xpath('//div/ul/li[contains(@id,"conleyhuang")]')
    
  • not() - 否定

    xpath('//div[not(text()="全村的笋都让你夺完了")]')
    
  • starts-with() - 获取以str开头的元素

    xpath('//div[stars-with(@class,"test")]')
    
  • last() - 最后一个节点

    xpath('//div/li[last()]') # 选择div下最后一个li节点
    xpath('//div/li[last()-1]') # 选择div下倒数第二个li节点
    
  • position() - 位置节点

    xpath('//div/li[position() = 1]') # 选择所有li中的第一个
    xpath('//div/li[position() > 3]') # 选择所有li中第三个之后的
    
  • count() - 节点数量

  • sum() - 节点的数值总和

  • avg() - 参数平均值

  • max() - 最大的参数

  • min() - 最小的参数

6. xpath轴(Axes)

XPath轴(XPath Axes)可定义某个相对于当前节点的节点集

表达式 描述
child 选取当前节点的所有子元素
parent 选取当前节点的父节点
descendant 选取当前节点的所有后代元素(子、孙等)
ancestor 选取当前节点的所有先辈(父、祖父等)
descendant-or-self 选取当前节点的所有后代元素(子、孙等)以及当前节点本身
ancestor-or-self 选取当前节点的所有先辈(父、祖父等)以及当前节点本身
preceding-sibling 选取当前节点之前的所有同级节点
following-sibling 选取当前节点之后的所有同级节点
preceding 选取文档中当前节点的开始标签之前的所有节点
following 选取文档中当前节点的结束标签之后的所有节点
self 选取当前节点
attribute 选取当前节点的所有属性
namespace 选取当前节点的所有命名空间节点。名称空间轴用来选取名称空间结点。每个元素结点都有一个专门名称空间结点表示每个作用域名称空间。
# 获取p标签下所有的a标签的href值
xpath('//*[@id="PageContent_C006_Col01"]/div[1]/div/p/descendant::a/@href') 

# 获取位置为四的li节点的所有属性值
xpath('//li[position()=4]/attribute::*') 

# from maersk
xpath(f'//a[contains(text(),"{sub_num}")]/../../td[2]/input')

# 获取文本为冻结的td标签同级之后的td标签的子标签中文本为查看的a标签的onclick属性值 😄
xpath('//td[text()="冻结"]/following-sibling::td/a[text()="查看"]/@onclick')[0]

# 获取span标签的先辈tr标签
driver.find_..._xpath(f"//span[contains(text(),'{yhzh}')]/ancestor::tr")

2152 字