• 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. 利用threading模块开线程

    一多线程的概念介绍 threading模块介绍 threading模块和multiprocessing模块在使用层面,有很大的相似性. 二.开启多线程的两种方式 1.创建线程的开销比创建进程的开销小, ...

  2. C++之路 #1

    一.C++介绍C++是C语言的继承,它可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计.C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计 ...

  3. 夯实Java基础系列11:深入理解Java中的回调机制

    目录 模块间的调用 多线程中的"回调" Java回调机制实战 实例一 : 同步调用 实例二:由浅入深 实例三:Tom做题 参考文章 微信公众号 Java技术江湖 个人公众号:黄小斜 ...

  4. MongoDB安装过程中出现service MongoDB failed to start,verify that you have sufficient privileges to start...

    win10系统下,安装MongoDB 64位, service MongoDB failed to start,verify that you have sufficient privileges t ...

  5. ElasticSearch实战系列三: ElasticSearch的JAVA API使用教程

    前言 在上一篇中介绍了ElasticSearch实战系列二: ElasticSearch的DSL语句使用教程---图文详解,本篇文章就来讲解下 ElasticSearch 6.x官方Java API的 ...

  6. PHP--网络协议相关知识

    HTTP状态码 HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码. HTTP状态码主要有5种,代表5种不同类型的响应: 1xx:信息性状态码,代表接 ...

  7. [Python] Python 学习记录(2)

    1.range(x,y) [x,y) >>> range(0,4) #0,1,2,3 >>> range(1,4) #1,2,3 2.dics dics.get(k ...

  8. Unknown column 'user_id' in 'where clause'

    mapper位置报错Unknown column 'user_id' in 'where clause' 可能是数据库中的字段user_id包含空格

  9. COGS 2089. 平凡的测试数据

    [题目描述] 树链剖分可以干什么? “可以支持在树中快速修改一个点信息,快速询问一条链信息” LCT可以干什么? “可以支持树链剖分支持的特性,并且支持快速链接两个棵树,或者断开某条边” 那我现在要出 ...

  10. C#刷遍Leetcode面试题系列连载(4) No.633 - 平方数之和

    上篇文章中一道数学问题 - 自除数,今天我们接着分析 LeetCode 中的另一道数学题吧~ 今天要给大家分析的面试题是 LeetCode 上第 633 号问题, Leetcode 633 - 平方数 ...