简介

XPathXML Path Language,一门在XMLHTML文档中查找信息的语言。

插件安装:

Chrome浏览器插件安装:XPath Helper

火狐浏览器插件安装:try XPath

常见语法

选取节点

XPath使用路径表达式来选取XML文档中的节点(集)。

表达式 描述 示例
nodename 选取此节点的所有子节点 div
// 查找所有子元素 //div
/ 查找直接子元素 /div
. 选取当前节点 ./div
.. 选取当前节点的父节点 ../div
@ 选取某个节点的属性 div[@id]

谓语

谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号中。常见谓语表达式如下:

表达式 描述 备注
/div/div[1] 选取div下的第一个div元素 xpath下标是从1开始的
/div/div[last()] 选取div下的最后一个div元素
/div/div[position()>3] 选取div下的前两个div元素
//div[@id] 选取所有拥有id属性的div元素
//div[@id="10"] 选取所有id为10的div元素
//div[contains(@class, "price")] 选取所有class包含price的div元素 模糊匹配

通配符

*表示通配符

通配符 描述 示例 结果
* 匹配任意节点 /div/* 选取div下的所有子元素
@* 匹配节点中的任何属性 //div[@*] 选取所有带有属性的div元素

选取多个路径

通过在表达式中使用|运算符,可以选取多个路径。示例:

'//div[@class="financial"] | //div[@class="john"]'

运算符

在所有使用的谓词中或选取节点时,可以使用运算符精确的选取节点

运算符 描述 实例 返回值
| 计算两个节点 //div | //dd 返回所用拥有div和dd元素的节点集
+ 加法 6+4 10
- 减法 6-4 2
* 乘法 6*4 24
div 除法 8 div 2 4
= 等于 price=9 如果是,返回True,否则返回False
!= 不等于 price!=9 同上
< 小于 price<9 同上
>= 小于或等于 price<=9 同上
or price=9 or price=10 有一个为真则返回True
and price=9 and price=10 同为真则返回True
mod 计算除法的余数 5 mod 2 1

比如要选取一个div节点,它的class"financial"id"john",可以使用//div[@class="financail" and id="john"]表达式。在某些拥有同一属性名和内容的元素中选取某个元素比较有用。

其他用法

使用contains选取包含属性

# div节点包含某个字符串的父节点下的td子节点
'//div[contains(text(), "标签文字包含某个字符串"]/../td'

使用tostring()将对象转换为字符串

# 使用xpath定位一个节点
s = html.xpath('//*[@id="testid"]')[0]
# s此时为<Element div at 0x2b6ffc8>对象
# 还原这个对象为html字符串
s2 = etree.tostring(s)
# s2现为:'<div id="testid">\n\t\t<h2>ÕâÀïÊǸöС±êÌâ</h2>\n\t\t<ol>\n\t\t\t<li data="one">1</li>\n\t\t\t<li data="two">2</li>\n\t\t\t<li data="three">3</li>\n\t\t</ol>\n\t\t<ul>\n\t\t\t<li code="84">84</li>\n\t\t\t<li code="104">104</li>\n\t\t\t<li code="223">223</li>\n\t\t</ul>\n\t</div>\n\t'

使用starts-with

'//div[starts-with(@class, "text")]'

使用not排除属性

# 排除包含某个属性的节点
'//tbody/tr[not(@class)]'
# 排除包含一个或两个属性的节点
'//tbody/tr[not(@class or @id)]'

选取倒数第二个标签

# 定位语法: position()=last()-1

'//tr[@bgcolor="#FFFFFF"]/td[position()=last()-1]//a'

使用 normalize-space

# normalize-space 函数删除了前部和尾部的空格, 并且把连续的空格串替换为一个单一的空格

'//*[starts-with(normalize-space(text()), "数读《共建“一带一路”倡议:进展、贡献和展望")]'

选取某个节点的兄弟节点

使用 preceding-sibling选取之前的兄弟节点,following-sibling选取之后的兄弟节点,例如:

# 选取 class 为 prompt 的 div 节点前的所有 class 为 post 的同级 div 节点
r.xpath('//div[@class="prompt"]/preceding-sibling::div[@class="post"]') # 选取 class 为 prompt 的 div 节点后的第一个兄弟节点
r.xpath('//div[@class="prompt"]/following-sibling::div[1]')

根据节点名字选取

节点名字可使用 name() 变量获取:

# 选取 div 下所有不是 p 标签的标签
r.xpath('//div/*[name()!="p"]')

选取祖先节点

使用 ancestor::

# 选取文本为 “办公电话” 的标签的 td 祖先标签的父级标签下的第二个子 td 标签下的文字
r.xpath('string(//*[text()="办公电话"]/ancestor::td/../td[2])')

更多

参考:

lxml库的使用

lxml是一个HTML/XML的解析器,解析和提取网页中的数据。它和正则一样,也是通过C语言实现的,是一款高性能的解析器。

用法示例

from lxml import etree

# 对字符串进行解析,同response对象
text = "some web source text..."
html = etree.HTML(text)
# 此时information是一个列表对象(xpath函数返回的永远是一个列表),要选取具体的数据需要给出下标
information = html.xpath('//div[@id="john"]//text()')
# 打印第一个
print(information[0]) # 对网页文件进行解析
html_element = etree.parse('somefile.html')
html = etree.tostring(html_element, encoding='utf-8').decode('utf-8')

备注

  1. etree.parse方法中的parser参数可以传递解析器,如果不指定默认为XML解析器,如果遇到不规范的HTML代码导致解析错误,可以自己创建HTML解析器;
  2. 获取文本通过text()方法,获取属性通过@属性名方法;
  3. 在某个标签下,再执行xpath函数获取子元素,应该在斜杠前加一个.,代表是从当前元素下获取,如./a[@class="test"]

参考

  1. Python爬虫:Xpath语法笔记
  2. lxml官方文档
  3. 【爬虫】xpath高级用法
  4. lxml官方文档-pdf版

最新文章

  1. HoloLens开发手记 - 测试 Testing
  2. java中如何获取昨天的当前日期
  3. IIS调试技巧
  4. android4.x获取(也可监测)外置sd路径和读写
  5. pcm跟.wav文件的关系
  6. win10 Enable developer Mode
  7. 烂泥:CentOS安装及配置TFTP服务器
  8. heredoc 和 nowdoc
  9. AngularJS 基础教程二:
  10. Stackoverflow上人气最旺的10个Java问题(转ImportNew)
  11. easyAR图钉功能实现相关
  12. ubuntu15.10 安装 virtualbox5.0
  13. 用ASP.NET Core 2.0 建立规范的 REST API
  14. String与StringBuffer之间的转换
  15. WPF常用TriggerAction用法 (一)
  16. linux下使用命令修改IP地址
  17. 【题解】 Luogu P4145 上帝造题的七分钟2 / 花神游历各国
  18. django admin后台显示中文
  19. 修改电脑自动休眠时间win10
  20. tp5系统核心设计提供了一些可能会需要的钩子(位置)

热门文章

  1. [loj2245]魔法森林
  2. spring rest小马哥
  3. Codeforces 587F - Duff is Mad(根号分治+AC 自动机+树状数组)
  4. 洛谷 P4621 - [COCI2012-2013#6] BAKTERIJE(exCRT)
  5. UOJ #228 - 基础数据结构练习题(势能线段树+复杂度分析)
  6. DTOJ 3987: 数学课
  7. 如何反向推断基因型文件中的参考碱基(REF/ALT)?
  8. 非标准的xml解析器的C++实现:二、解析器的基本构造:语法表
  9. 谈一谈 DDD
  10. ab命令执行压力测试