使用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 ...
随机推荐
- JS实现数组排序的方法
前言 排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列,当然排序也是算法中的一种,javascript内置的sort函数是多种排序算法的集合,数组在原数组上进 ...
- 高效解决「SQLite」数据库并发访问安全问题,只这一篇就够了
Concurrent database access 本文译自:https://dmytrodanylyk.com/articles/concurrent-database/ 对于 Android D ...
- POJ 2386——Lake Counting(DFS)
链接:http://poj.org/problem?id=2386 题解 #include<cstdio> #include<stack> using namespace st ...
- 从无到有,构建GIS + BIM大厦
声明:本文是一个系列原创(作者在GIS+BIM行业已有从业15年有余,还是个行业的小学生,文章内容不免有错误或者不当之处,敬请理解),旨在通过这个系列打造一个高性能,高可扩展的GIS+BIM框架,抛砖 ...
- GIT原理介绍
Git 是一套内容寻址文件系统.很不错.不过这是什么意思呢? 这种说法的意思是,Git 从核心上来看不过是简单地存储键值对(key-value).它允许插入任意类型的内容,并会返回一个键值,通过该键值 ...
- Nebula 架构剖析系列(零)图数据库的整体架构设计
Nebula Graph 是一个高性能的分布式开源图数据库,本文为大家介绍 Nebula Graph 的整体架构. 一个完整的 Nebula 部署集群包含三个服务,即 Query Service,S ...
- 从干将莫邪的故事说起--java比较操作注意要点
故事背景 <搜神记>: 楚干将.莫邪为楚王作剑,三年乃成.王怒,欲杀之.剑有雌雄.其妻重身当产.夫语妻曰:“吾为王作剑,三年乃成.王怒,往必杀我.汝若生子是男,大,告之曰:‘出户望南山,松 ...
- python模块常用用法
1.time模块(※※※※) import time #导入时间模块 print(time.time()) #返回当前时间的时间戳,可用于计算程序运行时间 print(time.localtime() ...
- Java并发——线程间的等待与通知
前言: 前面讲完了一些并发编程的原理,现在我们要来学习的是线程之间的协作.通俗来说就是,当前线程在某个条件下需要等待,不需要使用太多系统资源.在某个条件下我们需要去唤醒它,分配给它一定的系统资源,让它 ...
- GUI篇 tkinter (Label,Button)之一
import tkinterfrom tkinter import * # tkinter._test() # 实例化一个窗口对象base = tkinter.Tk()# 修改窗口的标题base.wm ...