Python:XPath爬虫基础

XPath(XML Path Language):XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索。XPath的选择功能十分强大,它提供了非常简明的路径选择表达式,另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等,几乎所有我们想要定位的节点,都可以用XPath来选择

1.XPath的解析原理

使用lxml库的etree对象来将需要被解析的HTML页面源码数据加载到该对象中,通过etree对象中的XPath方法结合其表达式来实现标签定位内容捕获

2.基本使用方法
  1. 首先通过pip install lxml来安装lxml库,该库是Python的一个解析库,支持HTMLXML的解析,支持XPath解析方式同时解析效率非常高。
  2. 将获取的HTML文档中的源码数据加载到etree对象中,一般来说都是结合爬虫使用。
#定义请求URL
url='http://www.baidu.com'
#定义请求头
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42'}
#向指定的URL发送request请求
req = urllib.request.Request(url=url, headers=headers)
#根据request请求获得response
res = urllib.request.urlopen(req)
#使用gbk编码对该结果进行读取
html = res.read().decode('gbk')
#实例化etree对象
etree.HTML(html)

注意:如果加载的是本地的文件那么可以使用etree.parse(filePath)来解析得到selector
上述解析得到的selector对象实则是PythonElement类,打印该对象会得到类似于[<Element div at 0x19d447658c8>]的结果,要切实获得其中的内容的话需要使用text()string(.)

3.XPath定位节点的方法

该部分主要介绍的是XPath用来定位节点所使用的表达式

nodename选取此节点的所有子节点
/表示的是从根节点开始定位。表示的是一个层级。
//表示的是多个层级。可以表示从任意位置开始定位。
.选取当前节点
选取当前节点的父节点
@选取属性
*通配符,选择所有元素节点与元素名
@*选取所有属性
[@attrib]选取具有给定属性的所有元素
[@attrib=‘value’]选取给定属性具有给定值的所有元素
[tag]选取所有具有指定元素的直接子节点
[tag=‘text’]选取所有具有指定元素并且文本内容是text节点

需要补充的是XPath也可以通过位置来定位节点:

  1. 使用索引的方式来选择特定的节点:如//ul[2]/li/text()
  2. 使用谓语的方式来选择特定的节点:如//ul[last()]/li/text()
text = '''<title>标题</title>
<body>
    <ul class='list1'>
        <li>列表1第1项</li>
        <li>列表1第2项</li>
    </ul>
    <p class='first'>文字1</p>
    <p class='second'>文字2</p>
    <ul class='list2'>
        <li>列表2第1项</li>
        <li>列表2第2项</li>
    </ul>
</body>'''

html = etree.HTML(text)
html.xpath('//ul[2]/li/text()') # 在xpath语句中使用索引,限制只在第二个ul中寻找
html.xpath('//ul/li[1]/text()') # 在每个ul中取第一个li
# ['列表2第1项', '列表2第2项']

html.xpath('//ul[last()]/li/text()') # 取最后一个
html.xpath('//ul[last()-1]/li/text()') # 倒数第二个
html.xpath('//ul[position()<3]/li/text()') # 前两个
4.Xpath提取内容的方法

XPath主要使用两个方法提取某个确定节点的内容:

  1. 提取标签的文本内容:使用/text()
  2. 提取标签的属性值:使用/@属性名

备注:执行的每一行XPath代码的输出在同行的注释中体现。

text = '''
<body>
    <h><a href='www.biaoti.com'>head</a></h>
    <p>段落1</p>
    <p>段落2</p>
</body>
'''
html = etree.HTML(text)
html.xpath('//h') # [<Element h at 0x2122e64e4c8>]
# 用//text() 提取标签内容
html.xpath('//h//text()') # ['head']
# /text()和//text()的区别在于不可以提取孙节点的内容
html.xpath('//h/a/text()') # ['head']
# xpath语法默认提取全部
html.xpath('//p/text()') # ['段落1', '段落2']
# 提取标签属性
html.xpath('//h/a/@href') # ['www.biaoti.com']

这里需要注意的是不论当前XPath搜索到的节点是单个还是多个都会将其封装到list中,如果想要获得具体的字符串值的话就需要通过索引进行访问。
此外,XPath库中提供了一个使用方法string(.)来代替text()完成特定的需要,由于后者所获得的内容是列表,因此如果想要将列表中的每个元素进行拼接的话不得不遍历列表才能实现,而前者可以直接将所有元素拼接起来转换为字符串形式,方便我们的使用。

4.XPath的使用规律总结
text = '''<title>标题</title>
<body>
    <ul class='list1'>
        <li>列表1第1项</li>
        <li>列表1第2项</li>
    </ul>
    <p class='first'>文字1</p>
    <p class='second'>文字2</p>
    <ul class='list2'>
        <li>列表2第1项</li>
        <li>列表2第2项</li>
    </ul>
</body>'''

from lxml import etree
html = etree.HTML(text)
html.xpath('//title/text()')[0] # '标题'
html.xpath("//p[@class='first']//text()")[0] # '文字1'
html.xpath("//p/text()") # ['文字1', '文字2']
html.xpath("//ul[@class='list1']/li/text()") # ['列表1第1项', '列表1第2项']

根据上述输出结果我们可以简单总结出XPath语法的规律:

  • XPath语法提取基于节点路径时只要输入一个字符串该字符串按照格式填写就能完成提取
  • 格式是一层层的节点,用/分离,通过[]在后面加入该节点的属性判断来唯一确定节点位置
  • 提取的结果永远是list,最后都要用索引提取
  • 不特殊指定的情况下会自动寻找所有满足条件的结果,可以在提取结果中用索引筛选,也可以在XPath内部使用索引
  • 语法中分隔节点有两种方法///,它们之间的差别在于,前者只寻找子节点,后者会寻找子孙所有后代的节点,将所有满足条件的全都找到
  • 一般来说先使用//是为了快速定位我们要找的位置的节点此后即可在基础上进行扩展和发挥
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值