爬虫 xpath
【一】介绍
【1】说明
-
xpath全程XML Path Language,即XML路径语言,用于确定XML文档中某部分位置的语言
-
主要用途
- 定位节点:通过节点名称、节点路径、节点属性等方式定位
- 选择节点:根据节点的属性、节点的文本内容、节点的位置等条件选择
- 提取数据:通过定位和选择节点,从XML文档中提取所需要的数据,并进一步分析
-
对比正则表达式
- xpath在网页分析中占据主导位置
【2】安装引入
- 安装
pip install lxml
- 导入
from lxml import etree
tree = etree.HTML(页面源码)
【二】XPath路径表达式
【1】基本路径表达式
- /:从根节点开始选取
- 例如:/body/div
- 选取根节点下的body下的所有div标签
- 例如:/body/div
- //:选取文档中任意位置的元素
- 例如://div
- 选取全文档的所有div标签
- 例如://div
- .:表示当前节点
- 例如:./div
- 选取当前节点下的所有div标签
- 例如:./div
- @:选取属性
- 例如://@href
- 选取全文档的href属性内容,是个列表
- 例如://@href
- …:父节点
- 例如://a[1]/…
- 返回第一a标签的父节点
- 例如://a[1]/…
【2】位置与条件选取[]
-
[]:通过索引或者条件选取,索引从1开始
- 例如://div[1]
- 选取第一个div
-
条件:
- last():选取最后一个元素
- 例如://div[last()]
- 选取最后一个div
- 例如://div[last() - 1]
- 选取倒数第二个div
- 例如://div[last()]
- position():基于位置的选择
- 例如://div[position <= 2]
- 选择前两个div
- 例如://div[position <= 2]
- @:配合属性选择
- 例如://div[@title]
- 选择含有title属性的div
- 例如://div[@price > 9.99]
- 选择含有price且大于9.99的所有div
- 例如://div[@title]
- last():选取最后一个元素
-
模糊查询
- contains:包含的关系
- 例如://div[contains(@id, ‘dd’)]
- 查询所有ID包含dd的div
- 例如://div[contains(@id, ‘dd’)]
- starts-with:以什么开头
- 例如://div[starts-with(@id, ‘dd’)]
- 查询所有ID以dd开头的div
- 例如://div[starts-with(@id, ‘dd’)]
- contains:包含的关系
【3】通配符
*
:匹配任意元素- 例如:/div/*
- 选择div下面的所有直接子元素
- 例如:/div/*
- @*:匹配任意属性
- 例如:/div/@*
- 返回div的所有属性值。是一个列表
- 例如://title[@*]
- 返回的是所有带属性的title标签
- 例如:/div/@*
- node():返回所有的直接子元素
- 例如:/div/node()
- 返回div下的所有内容
- 包括文本、注释、换行、标签
- 例如:/div/node()
【4】逻辑运算
-
|:若干路径或选择
- 例如://book/title | //book/price
- 选取book元素的所有title和price
- 满足一个条件即可
- 例如://book/title | //book/price
-
and:条件并列
- 例如://div[@id=‘d1’ and @class=‘c1’]
- 选择满足id是d1且class是c1的div
- 例如://div[@id=‘d1’ and @class=‘c1’]
【5】获取文本内容
- text():获取文本内容
- 方法一:写在xpath中
- 内部可以执行for循环
- 方法二:写在xpath外
- 需要手写for循环
from lxml import etreehtml = """
<div>
<p>杰弗里</p>
<p>一套豪华的六居室别墅</p>
</div>"""
tree = etree.HTML(html)
# 写在xpath中
text_list = tree.xpath('//div/p/text()')
print(text_list) # ['杰弗里', '一套豪华的六居室别墅']
# 写在xpath外面
p_list = tree.xpath('//div/p')
for p in p_list:print(p.text) # 杰弗里 # 一套豪华的六居室别墅
【6】节点轴选择
# 获取a标签的所有祖先节点
ancestors = html.xpath('//a/ancestor::*')
# 获取a标签的祖先节点中的div
div_ancestor_node = html.xpath('//a/ancestor::div')
# 获取第一个a标签的所有属性值
attribute_values = html.xpath('//a[1]/attribute::*')
# 获取第一个a标签的所有子节点
child_nodes = html.xpath('//a[3]/child::*')
# 获取第六个a标签的所有子孙节点
descendant_nodes = html.xpath('//a[3]/descendant::*')
# 获取第一个a标签之后的所有子孙节点
following_nodes = html.xpath('//a[1]/following::*')
# 获取第一个a标签之后的同级节点
following_sibling_nodes = html.xpath('//a[1]/following-sibling::*')