• XPath----XML路径语言

    • XPath概览

      • XPath是一门在XML文档中查找信息的语言,它提供了非常简洁明了的路径选择表达式。
    • XPath常用规则

      • 表达式 描  述
        nodename 选取此节点的所有子节点
        / 从当前节点选取直接子节点
        // 从当前节点选取子孙节点
        . 选取当前节点
        .. 选取当前节点的父节点
        @ 选取属性

        示例:   //title[@lang='eng']    它代表选择所有名称为title,同时属性lang的值为eng的节点

    • 实例引入

      • 处理HTML变量
         from lxml import etree
        
         html = etree.parse('./test.html', etree.HTMLParser())               # 直接对html文本进行解析
        result = etree.tostring(html)
        print(result.decode('utf-8')) # 输出:
        <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
        <html><body><div>
        <ul>
        <li class="item-O"><a href="linkl.html">first item</a></li>
        <li class="item-1"><a href="link2.html">second item</a></li>
        <li class="item-inactive"><a href="link3.html">third item</a></li>
        <li class="item-1"><a href="link4.html">fourth item</a></li>
        <li class="item-0"><a href="link5.html">fifth item</a>
        </li></ul>
        </div>
        </body></html>

        处理HTML文本

        HTML文本内容同HTML变量内容一样

    • 所有节点

      # 用 // 开头的XPath规则来选取所有符合要求的节点
      
      xpath()获取节点
    •  from lxml import etree
      
       html = etree.parse('./test.html', etree.HTMLParser())
      result = html.xpath('//*')
      print(result) # 输出:
      [<Element html at 0x112829bc8>, <Element body at 0x112829d08>, <Element div at 0x112829d48>, <Element ul at 0x112829d88>, <Element li at 0x112829dc8>, <Element a at 0x112829e48>, <Element li at 0x112829e88>, <Element a at 0x112829ec8>, <Element li at 0x112829f08>, <Element a at 0x112829e08>, <Element li at 0x112fc21c8>, <Element a at 0x112fc2208>, <Element li at 0x112fc2248>, <Element a at 0x112fc2288>]
       from lxml import etree
      
       html = etree.parse('./test.html', etree.HTMLParser())               # 直接对html文本进行解析
      result = html.xpath('//li')
      print(result, result[0], sep='\n') # 输出:
      [<Element li at 0x10dffcec8>, <Element li at 0x10dffcf08>, <Element li at 0x10dffcf48>, <Element li at 0x10dffcf88>, <Element li at 0x10dffcfc8>]
      <Element li at 0x10dffcec8>

      两个例子对比

    • 子节点

       from lxml import etree
      
       html = etree.parse('./test.html', etree.HTMLParser())               # 直接对html文本进行解析
      result = html.xpath('//li/a')
      print(result) # 输出:
      [<Element a at 0x11b316dc8>, <Element a at 0x11b316e08>, <Element a at 0x11b316e48>, <Element a at 0x11b316e88>, <Element a at 0x11b316ec8>] # //li用于选中所有li节点,/a用于选中li节点的所有直接子节点,即获得所有li节点的所有直接a子节点
       from lxml import etree
      
       html = etree.parse('./test.html', etree.HTMLParser())               # 直接对html文本进行解析
      result = html.xpath('//ul//a')
      print(result) # 输出:
      [<Element a at 0x112930d88>, <Element a at 0x112930dc8>, <Element a at 0x112930e08>, <Element a at 0x112930e48>, <Element a at 0x112930e88>]

      第一个例子用//li/a,第二个例子用//ul//a,输出结果一样

    • 父节点

       from lxml import etree
      
       html = etree.parse('./test.html', etree.HTMLParser())               # 直接对html文本进行解析
      result = html.xpath('//a[@href="link4.html"]/../@class')
      # result = html.xpath('//a[@href="link4.html"]/parent::*/@class)
      print(result) # 输出:
      ['item-1'] # 获取父节点
      ..
      或者
      parent::
    • 属性匹配

       from lxml import etree
      
       html = etree.parse('./test.html', etree.HTMLParser())               # 直接对html文本进行解析
      result = html.xpath('//li[@class="item-0"]')
      print(result) # 输出:
      [<Element li at 0x115357d08>]
    • 文本获取

      # XPath 中的text()方法获取节点中的文本
       from lxml import etree
      
       html = etree.parse('./test.html', etree.HTMLParser())               # 直接对html文本进行解析
      result = html.xpath('//li[@class="item-0"]/text()')
      print(result) # 输出:
      ['\n'] # 输出结果没有获得任何文本,只获得一个换行符,这是因为XPath中text()前面是/,而此处/的含义是选取直接子节点,很明显li的子节点都是a节点,文本都是在a节点内部的,所以这里匹配到的结果就是被修正后的li节点内部的换行符,因为自动修正的li节点的尾标签换行来。 # 上面XPath语句选中的HTML是:
      <li class="item-O"><a href="linkl.html">first item</a></li>
      <li class="item-0"><a href="link5.html">fifth item</a>
      # 修正后的HTML:
      <li class="item-O"><a href="linkl.html">first item</a></li>
      <li class="item-0"><a href="link5.html">fifth item</a>
      </li>
      # 获取li节点内部的文本的两种方式
      # 方式1、先获取a节点再回去文本
      # 方式2、使用//
       # 方式1
      from lxml import etree html = etree.parse('./test.html', etree.HTMLParser())
      result = html.xpath('//li[@class="item-0"]/a/text()')
      print(result)
      # 输出:
      ['fifth item'] # 方式2
      from lxml import etree html = etree.parse('./test.html', etree.HTMLParser())
      result = html.xpath('//li[@class="item-0"]//text()')
      print(result)
      # 输出:
      ['fifth item', '\n']
    • 属性获取

      # 用@可以获取属性
       from lxml import etree
      
       html = etree.parse('./test.html', etree.HTMLParser())
      result = html.xpath('//li/a/@href')
      print(result) # 输出:
      ['linkl.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html']
    • 属性多值匹配

      # 有些属性可能有多个值,那么要匹配这些属性,则需要用到contains()函数
    • contains()方法,第一个参数传入属性名称,第二个参数传入属性值
       from lxml import etree
      
       # 这里的HTML文本中的li节点的class属性有两个值li和li-first
      text = '''
      <li class="li li-first"><a href="link.html">first item</a></li>
      '''
      html = etree.HTML(text)
      # 获取text中的所有li节点中class属性是li的文本
      result = html.xpath('//li[contains(@class, "li")]/a/text()')
      print(result) # 输出:
      ['first item']
    • 多属性匹配

       from lxml import etree
      
       text = '''
      <li class="li li-first" name="item"><a href="link.html">first item</a></li>
      '''
      html = etree.HTML(text)
      result = html.xpath('//li[contains(@class, "li") and @name="item"]/a/text()')
      print(result) # 输出:
      ['first item']

      运算符及其介绍

      运算符 描  述 实。例 返回值
      or price=9.80 or price=9.70

      如果 price 是 9.80,则返回 true。

      如果 price 是 9.50,则返回 false。

      and price>9.00 and price<9.90

      如果 price 是 9.80,则返回 true。

      如果 price 是 8.50,则返回 false。

      mod 计算除法的余数 5 mod 2 1
      | 计算两个节点集 //book | //cd 返回所有拥有 book 和 cd 元素的节点集
      + 加法 6 + 6 12
      - 减法 6 - 6 0
      * 乘法 6 * 6 36
      div 除法 6 div 6 1
      = 等于 price=9.80

      如果 price 是 9.80,则返回 true。

      如果 price 不是 9.90,则返回 false。

      != 不等于 price!=9.80

      如果 price 不是 9.90,则返回 true。

      如果 price 是 9.80,则返回 false。

       <  小于  age<20

      如果 age 小于 20,则返回 true。

      如果 age 不小于 20,则返回 false。

       <= 小于等于   age<=20

      如果 age 小于等于 20,则返回 true。

      如果 age 大于 20,则返回 false

       >  大于  age>20

      如果 age 大于 20,则返回 true。

      如果 age 不大于 20,则返回 false

       >=  大于等于  age>=20

      如果 age 大于等于 20,则返回 true。

      如果 age 小于 20,则返回 false

    • 顺序选择

      # 利用中括号传入索引的方法获取特定次序的节点
       from lxml import etree
      
       text = '''
      <div>
      <ul>
      <li class="item-O"><a href="linkl.html">first item</a></li>
      <li class="item-1"><a href="link2.html">second item</a></li>
      <li class="item-inactive"><a href="link3.html">third item</a></li>
      <li class="item-1"><a href="link4.html">fourth item</a></li>
      <li class="item-0"><a href="link5.html">fifth item</a>
      </ul>
      </div>
      '''
      html = etree.HTML(text)
      result1 = html.xpath('//li[1]/a/text()') # 选取第一个li节点
      result2 = html.xpath('//li[last()]/a/text()') # 选取最后一个li节点
      result3 = html.xpath('//li[position()<3]/a/text()') # 选取位置小于3的li节点
      result4 = html.xpath('//li[last()-2]/a/text()') # 选取倒数第3个li节点 print(result1, result2, result3, result4, sep='\n') # 输出:
      ['first item']
      ['fifth item']
      ['first item', 'second item']
      ['third item']
    • 节点轴选择

      # ancestor轴、attribute轴、child轴、descendant轴、following轴、following-sibling轴 等
       from lxml import etree
      
       text = '''
      <div>
      <ul>
      <li class="item-O"><a href="linkl.html"><span>first item</span></a></li>
      <li class="item-1"><a href="link2.html">second item</a></li>
      <li class="item-inactive"><a href="link3.html">third item</a></li>
      <li class="item-1"><a href="link4.html">fourth item</a></li>
      <li class="item-0"><a href="link5.html">fifth item</a>
      </ul>
      </div>
      '''
      html = etree.HTML(text)
      result1 = html.xpath('//li[1]/ancestor::*') # 获取第1个li节点的所有祖先节点
      result2 = html.xpath('//li[1]/ancestor::div') # 获取第1个li节点的这个祖先节点
      result3 = html.xpath('//li[1]/attribute::*') # 获取第1个li节点的所有属性值
      result4 = html.xpath('//li[1]/child::a[@href="link.html"]') # 获取所有(href属性值为link.html的a节点)直接子节点
      result5 = html.xpath('//li[1]/descendant::span') # 获取所有子孙节点(获取span节点)
      result6 = html.xpath('//li[1]/following::*[2]') # 获取当前节点之后的第2个捷点
      result7 = html.xpath('//li[1]/following-sibling::*') # 获取当前节点之后的所有同级节点 print(result1, result2, result3, result4, result5, result6, result7, sep='\n') # 输出:
      [<Element html at 0x102e9f088>, <Element body at 0x10350fe08>, <Element div at 0x10350fd88>, <Element ul at 0x10350fd08>]
      [<Element div at 0x10350fd88>]
      ['item-O']
      []
      [<Element span at 0x10350fec8>]
      [<Element a at 0x10350fe88>]
      [<Element li at 0x10350ff48>, <Element li at 0x10350ff88>, <Element li at 0x10350ffc8>, <Element li at 0x111ba0048>]

使用XPath的更多相关文章

  1. xpath提取多个标签下的text

    title: xpath提取多个标签下的text author: 青南 date: 2015-01-17 16:01:07 categories: [Python] tags: [xpath,Pyth ...

  2. C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)

    第一次接触HtmlAgilityPack是在5年前,一些意外,让我从技术部门临时调到销售部门,负责建立一些流程和寻找潜在客户,最后在阿里巴巴找到了很多客户信息,非常全面,刚开始是手动复制到Excel, ...

  3. 在Java中使用xpath对xml解析

    xpath是一门在xml文档中查找信息的语言.xpath用于在XML文档中通过元素和属性进行导航.它的返回值可能是节点,节点集合,文本,以及节点和文本的混合等.在学习本文档之前应该对XML的节点,元素 ...

  4. XPath 学习二: 语法

    XPath 使用路径表达式来选取 XML 文档中的节点或节点集.节点是通过沿着路径 (path) 或者步 (steps) 来选取的. 下面列出了最有用的路径表达式: 表达式 描述 nodename 选 ...

  5. xpath 学习一: 节点

    xpath 中,有七种类型的节点: 元素.属性.文本.命名空间.处理指令.注释.以及根节点 树的根成为文档节点或者根节点. 节点关系: Parent, Children, sibling(同胞), A ...

  6. Python爬虫利器三之Xpath语法与lxml库的用法

    前面我们介绍了 BeautifulSoup 的用法,这个已经是非常强大的库了,不过还有一些比较流行的解析库,例如 lxml,使用的是 Xpath 语法,同样是效率比较高的解析方法.如果大家对 Beau ...

  7. 使用python+xpath 获取https://pypi.python.org/pypi/lxml/2.3/的下载链接

    使用python+xpath 获取https://pypi.python.org/pypi/lxml/2.3/的下载链接: 使用requests获取html后,分析html中的标签发现所需要的链接在& ...

  8. 关于robotframework,app,appium的xpath定位问题及常用方法

    关于类似的帖子好像很多,但是没有找到具体能帮我解决问题的办法.还是自己深究了好久才基本知道app上面的xpath定位和web上的不同点: 先放一个图: A,先说说不用xpath的场景,一般是用于存在i ...

  9. Selenium Xpath Tutorials - Identifying xpath for element with examples to use in selenium

    Xpath in selenium is close to must required. XPath is element locator and you need to provide xpath ...

  10. xpath定位中starts-with、contains和text()的用法

    starts-with 顾名思义,匹配一个属性开始位置的关键字 contains 匹配一个属性值中包含的字符串 text() 匹配的是显示文本信息,此处也可以用来做定位用 eg //input[sta ...

随机推荐

  1. JS实现数组排序的方法

    前言 排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列,当然排序也是算法中的一种,javascript内置的sort函数是多种排序算法的集合,数组在原数组上进 ...

  2. 高效解决「SQLite」数据库并发访问安全问题,只这一篇就够了

    Concurrent database access 本文译自:https://dmytrodanylyk.com/articles/concurrent-database/ 对于 Android D ...

  3. POJ 2386——Lake Counting(DFS)

    链接:http://poj.org/problem?id=2386 题解 #include<cstdio> #include<stack> using namespace st ...

  4. 从无到有,构建GIS + BIM大厦

    声明:本文是一个系列原创(作者在GIS+BIM行业已有从业15年有余,还是个行业的小学生,文章内容不免有错误或者不当之处,敬请理解),旨在通过这个系列打造一个高性能,高可扩展的GIS+BIM框架,抛砖 ...

  5. GIT原理介绍

    Git 是一套内容寻址文件系统.很不错.不过这是什么意思呢? 这种说法的意思是,Git 从核心上来看不过是简单地存储键值对(key-value).它允许插入任意类型的内容,并会返回一个键值,通过该键值 ...

  6. Nebula 架构剖析系列(零)图数据库的整体架构设计

    Nebula Graph 是一个高性能的分布式开源图数据库,本文为大家介绍 Nebula Graph 的整体架构. 一个完整的 Nebula 部署集群包含三个服务,即  Query Service,S ...

  7. 从干将莫邪的故事说起--java比较操作注意要点

    故事背景 <搜神记>: 楚干将.莫邪为楚王作剑,三年乃成.王怒,欲杀之.剑有雌雄.其妻重身当产.夫语妻曰:“吾为王作剑,三年乃成.王怒,往必杀我.汝若生子是男,大,告之曰:‘出户望南山,松 ...

  8. python模块常用用法

    1.time模块(※※※※) import time #导入时间模块 print(time.time()) #返回当前时间的时间戳,可用于计算程序运行时间 print(time.localtime() ...

  9. Java并发——线程间的等待与通知

    前言: 前面讲完了一些并发编程的原理,现在我们要来学习的是线程之间的协作.通俗来说就是,当前线程在某个条件下需要等待,不需要使用太多系统资源.在某个条件下我们需要去唤醒它,分配给它一定的系统资源,让它 ...

  10. GUI篇 tkinter (Label,Button)之一

    import tkinterfrom tkinter import * # tkinter._test() # 实例化一个窗口对象base = tkinter.Tk()# 修改窗口的标题base.wm ...