使用XPath
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的更多相关文章
- xpath提取多个标签下的text
title: xpath提取多个标签下的text author: 青南 date: 2015-01-17 16:01:07 categories: [Python] tags: [xpath,Pyth ...
- C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)
第一次接触HtmlAgilityPack是在5年前,一些意外,让我从技术部门临时调到销售部门,负责建立一些流程和寻找潜在客户,最后在阿里巴巴找到了很多客户信息,非常全面,刚开始是手动复制到Excel, ...
- 在Java中使用xpath对xml解析
xpath是一门在xml文档中查找信息的语言.xpath用于在XML文档中通过元素和属性进行导航.它的返回值可能是节点,节点集合,文本,以及节点和文本的混合等.在学习本文档之前应该对XML的节点,元素 ...
- XPath 学习二: 语法
XPath 使用路径表达式来选取 XML 文档中的节点或节点集.节点是通过沿着路径 (path) 或者步 (steps) 来选取的. 下面列出了最有用的路径表达式: 表达式 描述 nodename 选 ...
- xpath 学习一: 节点
xpath 中,有七种类型的节点: 元素.属性.文本.命名空间.处理指令.注释.以及根节点 树的根成为文档节点或者根节点. 节点关系: Parent, Children, sibling(同胞), A ...
- Python爬虫利器三之Xpath语法与lxml库的用法
前面我们介绍了 BeautifulSoup 的用法,这个已经是非常强大的库了,不过还有一些比较流行的解析库,例如 lxml,使用的是 Xpath 语法,同样是效率比较高的解析方法.如果大家对 Beau ...
- 使用python+xpath 获取https://pypi.python.org/pypi/lxml/2.3/的下载链接
使用python+xpath 获取https://pypi.python.org/pypi/lxml/2.3/的下载链接: 使用requests获取html后,分析html中的标签发现所需要的链接在& ...
- 关于robotframework,app,appium的xpath定位问题及常用方法
关于类似的帖子好像很多,但是没有找到具体能帮我解决问题的办法.还是自己深究了好久才基本知道app上面的xpath定位和web上的不同点: 先放一个图: A,先说说不用xpath的场景,一般是用于存在i ...
- 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 ...
- xpath定位中starts-with、contains和text()的用法
starts-with 顾名思义,匹配一个属性开始位置的关键字 contains 匹配一个属性值中包含的字符串 text() 匹配的是显示文本信息,此处也可以用来做定位用 eg //input[sta ...
随机推荐
- 利用threading模块开线程
一多线程的概念介绍 threading模块介绍 threading模块和multiprocessing模块在使用层面,有很大的相似性. 二.开启多线程的两种方式 1.创建线程的开销比创建进程的开销小, ...
- C++之路 #1
一.C++介绍C++是C语言的继承,它可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计.C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计 ...
- 夯实Java基础系列11:深入理解Java中的回调机制
目录 模块间的调用 多线程中的"回调" Java回调机制实战 实例一 : 同步调用 实例二:由浅入深 实例三:Tom做题 参考文章 微信公众号 Java技术江湖 个人公众号:黄小斜 ...
- 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 ...
- ElasticSearch实战系列三: ElasticSearch的JAVA API使用教程
前言 在上一篇中介绍了ElasticSearch实战系列二: ElasticSearch的DSL语句使用教程---图文详解,本篇文章就来讲解下 ElasticSearch 6.x官方Java API的 ...
- PHP--网络协议相关知识
HTTP状态码 HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码. HTTP状态码主要有5种,代表5种不同类型的响应: 1xx:信息性状态码,代表接 ...
- [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 ...
- Unknown column 'user_id' in 'where clause'
mapper位置报错Unknown column 'user_id' in 'where clause' 可能是数据库中的字段user_id包含空格
- COGS 2089. 平凡的测试数据
[题目描述] 树链剖分可以干什么? “可以支持在树中快速修改一个点信息,快速询问一条链信息” LCT可以干什么? “可以支持树链剖分支持的特性,并且支持快速链接两个棵树,或者断开某条边” 那我现在要出 ...
- C#刷遍Leetcode面试题系列连载(4) No.633 - 平方数之和
上篇文章中一道数学问题 - 自除数,今天我们接着分析 LeetCode 中的另一道数学题吧~ 今天要给大家分析的面试题是 LeetCode 上第 633 号问题, Leetcode 633 - 平方数 ...