xpath模块

xpath简介

XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 都构建于 XPath 表达之上。

<html>
    <body>
        <div>
            <p>Hello world<p>
            <a href="/home">Click here</a>
        </div>
    </body>
</html>

XML文档中常见的节点包括:

  • 根节点:html
  • 元素节点:html,body,div,p,a
  • 属性节点:href
  • 文本节点:xpath简介

XML文档中常见的节点间关系:

  • 父子关系:例如上面的<p>, <a>都是<div>的子节点,反之,<div>则是<p>,<a>标签的父节点
  • 兄弟关系:例如<p>,<a>标签是兄弟节点
  • 祖先/后代:例如,<body>、<div>、<p>、<a> 都是 <html> 的后代节点,反之,也称 <html> 是<body>、<div>、<p>、<a> 的祖先节点

对于网页解析来说,xpath 比 re 更加方便简洁,故 Python 中也提供相应的模块 —— lxml.etree

安装

pip3 install lxml

使用

aaa = """
<html>
    <head>
        <meta charset="UTF-8"/>
        <link rel="stylesheet" href="style/base.css"/>
        <title>Example website</title>
    </head>
    <body>
        <div id="images" class="content">
            <a href="image1.html">Image1<img src="image1.jpg"/></a>
            <a href="image2.html">Image2<img src="image2.jpg"/></a>
            <a href="image3.html">Image3<img src="image3.jpg"/></a>
        </div>
    </body>
</html>
"""

导入模块

from lxml import etree

构造对象

html = etree.HTML(aaa)    # 构造 lxml.etree._Element 对象
# result = etree.tostring(html) # 代码补全功能
# 假如我们得到的 XML 文档不是规范的文档,该对象将会自动补全缺失的闭合标签
# 我们可以使用 tostring() 方法将对象转化成 bytes 类型的字符串
# 再使用 decode('utf-8') 方法将 bytes 类型的字符串转化为 str 类型的字符串
print(etree.tostring(html).decode('utf-8'))

匹配数据

我们可以使用 xpath() 方法进行匹配

xpath常用规则

表达式 描述
nodename 选择这个节点名的所有子节点
/ 从当前节点选择直接子节点
// 从当前节点选取子孙节点
. 选择当前节点
.. 选取当前节点的父节点
@ 选取属性
E/* 选取E节点下所有的子节点
| 选取若干个路径
E/text() 获取E节点下子节点的文本内容
E/string() 获取E节点下子孙节点的文本内容,不支持获取数字类型
E/data() 和string()通用,但是不建议使用,除非获取数字类型

具体讲解+案例

  • /表示子代节点,如获取<head>标签下的<title>子节点

    test = html.xpath('/html/head/title')
    
  • //表示后代节点,如获取根节点下所有的<a>节点

    test = html.xpath('//a')
    
  • *表示所有节点,如获取<html>节点下所有的节点

    test = html.xpath('/html/*')
    
  • text() 表示文本节点,例如 获取<title>节点下的子节点中的文本节点

    test = html.xpath('/html/head/title/text()')
    
  • @attr表示属性节点,如获取<a>标签的href属性

    test = html.xpath('//a/@href')
    
  • |代表选取多个标签,如获取<head>标签下的<title>子节点 和 获取根节点下所有的<a>节点

    test = html.xpath('/html/head/title|//a')
    
  • 谓语用于匹配指定的标签

    1. 指定第二个 <a> 标签

      test = html.xpath('//a[2]')
      
    2. 指定前两个 <a> 标签

      test = html.xpath('//a[position()<=2]')
      
    3. 指定带有 href 属性的<a> 标签

      test = html.xpath('//a[@href]')
      
    4. 指定带有 href 属性且值为 image1.html 的 <a> 标签

      test = html.xpath('//a[@href="image1.html"]')
      
    5. 指定带有 href 属性且值包含 image 的 <a> 标签

      test = html.xpath('//a[contains(@href,"image")]')
      
    6. 指定最后一个<a>标签

      test = html.xpath('//a[last()]')
      
    7. 指定倒数第二个<a>标签

      test = html.xpath('//a[last()-1]')
      

_Element 对象

xpath 方法返回字符串或者匹配列表,匹配列表中的每一项都是 lxml.etree._Element 对象

下面主要介绍一下 _Element 对象的常用属性与方法:

我们先用 xpath 方法得到匹配列表 tests 作为测试样例,tests 中的每一项都是一个 _Element 对象

test = html.xpath('//a[@href="image1.html"]')
obj = test[0]
  • tag 返回标签名

    obj.tag      # 'a'
    
  • attrib 返回属性与值组成的字典

    obj.attrib    # {'href': 'image1.html'}
    
  • get() 返回指定属性的值

    obj.get('href')    # 'image1.html'
    
  • text 返回文本值

    obj.text    # 'Image1'
    
posted @ 2019-11-05 16:06  蔚蓝的爱  阅读(192)  评论(0编辑  收藏  举报