2019年4月29日

Xpath用法总结

简介

XPath,全称 XML Path Language,即 XML 路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻 XML 文档的,但是它同样适用于 HTML 文档的搜索。是爬虫中用来提取结构化数据比较常用的一种方法,工作中用的比较多,遂记录一下它的常用用法

用法

先提前说明一下 / 和 // 的区别

/ 表示文档里根下的那些节点
// 表示文档里的任何位置的节点

常规用法

表示式 说明
/node 表示查找节点名称为 node 的节点
./node 表示在当前节点下查找名称为 node 的节点
//node 表示查找所有名称为 node 的节点
//* 表示查找所有节点,但是排除文本节点
//text() 表示查找所有文本节点
//text()[contains(.,’测试’)] 表示查找所有包含 “测试”文字的节点
//node[contains(text(),’测试’)] 表示查找所有包含 “测试”文字的 node 节点
//node[@attr] 表示所有包含 attr 属性的节点 ( attr 可以是 id,class 等 )
//node[not(@attr)] 表示不包含 attr 属性的节点 ( attr 可以是id,class 等 )
//node[@attr1 and not(@attr2)] 表示包含 attr1 属性、不包含 attr2 属性的节点
//node[@id=’s’] 表示所有 id 值为 “s” 的节点
//node[@id!=’s’] 表示所有 id 值不为 “s” 的节点
//node[start-with(@attr,’nice’)] 等价于 //node[substring(@attr, 1,4)=’nice’] 表示查找所有 attr 属性值以 “nice” 开头的节点
//node[end-with(@attr,’nice’)] 等价于 //node[substring(@attr, string-length(attr) – string-length(‘nice’) + 1) = ‘nice’] 表示查找所有 attr 属性值以 “nice” 结尾的节点
//node[contains(@attr,’nice’)] 表示查找所有 attr 属性值包含 “nice” 开头的节点
//node//@attr 表示获取 node 节点的 attr 属性值 ( attr 可以是id,class等 )
//node//text() 表示获取 node 节点的文本值
string(//nodes//node) 表示获取 nodes 节点下 node 节点的所有文本字符串值
//nodes[@id]//nodes[0] 表示查找含有 id 属性的 nodes 节点下的第一个 node 节点
//nodes[@id]//node[last()] 表示查找含有 id 属性的 nodes 结点下的最后一个 node 结点
//nodes[@id]//node[position()<4] 表示递归查找 nodes 结点下索引小于 4 的 node 结点
//nodes[@id]//node[position()<last()] 表示递归查找含有 id 属性的 nodes 结点下除最后一个结点外的 node 结点
//nodes/child::node()[name()=’node’] 表示查找 nodes 结点下结点名称为 node 的子结点
//nodes//child::node() 等同于 //nodes//node 表示查找 nodes 下的 node 子结点
//nodes//node//attribute::id 等同于 //nodes//node//@id 表示获取 nodes 结点下的 node 结点的 id 属性值
//dt/following-sibling::dd[1]//text() 表示获取节点 dt 的第一个弟弟节点 dd 的文本值
//div[@id=’D’]/preceding-sibling::div[1] 表示定位 id 为 “D” 的 div 节点的第一个哥哥节点 div

Xpath 轴表达式

轴可以在位置路径中快捷引用特定的节点(忽略属性和名称空间节点),上面我们用到的 child、following-sibling 等就是轴,下面列举一些常用的轴。

文档轴 用途
parent 选择当前节点的父节点
child 选择当前节点的子节点
attribute 选择当前节点的所有属性
ancestor 选择当前节点的所有祖先,包括父节点、父节点的父节点等等
ancestor-or-self 选择当前节点的祖先以及当前节点本身
descendant 选择当前节点的所有后代,包括子节点、子节点的子节点等等
descendant-or-self 选择当前节点的后代以及当前节点本身
preceding 选择整个文档中出现在当前节点前面的所有节点
preceding-sibling 选择文档中出现在当前节点前面的所有同胞节点(即与当前节点同级的节点)
following 选择整个文档中出现在当前节点后面的所有节点
following-sibling 选择文档中出现在当前节点后面的所有同胞节点(即与当前节点同级的节点)

Python 中使用 Xpath

lxml是python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高
## 安装 lxml 包

pip install lxml
pip install requests

使用

import requests
from lxml import etree

# 先用 requests 请求下来 HTML 文档
content=requests.get(url).content
# 把 HTML 文档转成 utf-8 格式
html =content.decode("utf-8")
# 将 HTML 文档转换成能被 xpath 匹配的格式
selector = etree.HTML(html)
# 直接使用
print selector.xpath("//div[contains(@data-attrid,'founded')]//span[2]//text()")[0]

问题记录

Xpath 中文定位报错

有时候我们的 Xpath 表达式中会用到中文,但是有时候会报错,记录如下

解决方案

方法1. 直接用 xpath 中变量语法 ( $符号加变量名 ) $title, 传参 title 即可(推荐)

links = sel.xpath('//i[contains(@title,$title)]/following-sibling::a/@href', title="置顶").extract()

方法2. 将整个 xpath 语句转成 unicode

links = sel.xpath(u'//i[contains(@title,"置顶")]/following-sibling::a/@href').extract()

方法3. xpath 语句用已转成 unicode 的 title 变量

title = u"置顶"
links = sel.xpath('//i[contains(@title,"%s")]/following-sibling::a/@href' %(title)).extract()

参考链接

XPath各种表达式的应用
Python selenium —— 父子、兄弟、相邻节点定位方式详解

You may also like...

1 Response

  1. Selina说道:

    Hi, very nice website, cheers!
    ——————————————————
    Need cheap and reliable hosting? Our shared plans start at $10 for an year and VPS plans for $6/Mo.
    ——————————————————
    Check here: https://www.good-webhosting.com/

发表评论

电子邮件地址不会被公开。 必填项已用*标注