• 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. 【ADO.NET基础】加密方法公共类

    各种加密方法集锦: using System; using System.Security.Cryptography; using System.Text; using System.IO; usin ...

  2. mysql初识笔记

    一.初始mysql mysql介绍: mysql版本: 版本号=3个数字+1个后缀 mysql-5.0.9-beta 5 0 9 Beta 主版本号 发行级别 发行稳定级别 发行系列 发行系列的版本号 ...

  3. 在 ASP.NET Core 项目中使用 AutoMapper 进行实体映射

    一.前言 在实际项目开发过程中,我们使用到的各种 ORM 组件都可以很便捷的将我们获取到的数据绑定到对应的 List<T> 集合中,因为我们最终想要在页面上展示的数据与数据库实体类之间可能 ...

  4. 同时支持EF+Dapper的混合仓储,助你快速搭建数据访问层

    背景 17年开始,公司开始向DotNet Core转型,面对ORM工具的选型,当时围绕Dapper和EF发生了激烈的讨论.项目团队更加关注快速交付,他们主张使用EF这种能快速开发的ORM工具:而在线业 ...

  5. Android_基于监听的事件处理机制

    一.引言 在经过几天的学习之后, 首先熟悉了几大基本布局以及一些常用控件的使用方法,目前正在学习如何实现一个基本的登录注册界面及其功能,而实现功能就需要我们采用事件处理机制来进行调用事件处理方法.以下 ...

  6. Java 多线程爬虫及分布式爬虫架构探索

    这是 Java 爬虫系列博文的第五篇,在上一篇 Java 爬虫服务器被屏蔽,不要慌,咱们换一台服务器 中,我们简单的聊反爬虫策略和反反爬虫方法,主要针对的是 IP 被封及其对应办法.前面几篇文章我们把 ...

  7. .NET Core 3.0中IAsyncEnumerable<T>有什么大不了的?

    .NET Core 3.0和C# 8.0最激动人心的特性之一就是IAsyncEnumerable<T>(也就是async流).但它有什么特别之处呢?我们现在可以用它做哪些以前不可能做到的事 ...

  8. django自关联,auth模块

    一.自关联 写蛮好的一篇博客:https://www.cnblogs.com/Kingfan1993/p/9936541.html 1.一对多关联 1.表内自关联是指表内数据相关联的对象和表是相同字段 ...

  9. insert增数据详解

    查看表结构: desc 表名; describe的缩写,意为描述 增加数据不会改变表的结构,只是增加了行. 创建一张表: mysql> create table class( -> id ...

  10. PHP 插入排序 -- 希尔排序

    1.希尔排序 -- Shell Insertion Sort 时间复杂度:数学家正在勤劳的探索! 适用条件: 直接插入排序的改进,主要针对移动次数的减少,这取决于"增量队列"的取值 ...