3.1 XPath的使用

目录

3.1.1 XPath的作用

3.1.2 XPath使用前提

3.1.3 XPath的使用

(1)属性匹配和获取一个属性值节点的内容 

(2)属性多值匹配

(3)获取<>中的内容

(4)多属性匹配

(5)运算符及其介绍 

(6)按序选择

3.1.4 使用 XPath 过程中的问题

(1) 遍历节点时,解析用 // 出现的问题


3.1.1 XPath的作用

        解析网页,与正则表达式异曲同工

3.1.2 XPath使用前提

        需要从lxml库导入etree模块,且xpath不能直接对字符串进行解析,需要构造解析对象。

        这里以爬取Scrape | Movie中的电影名、种类、信息、剧情简介、分数为例(爬取目标如下图)。

       代码解释

from lxml import etree
import requests

url = 'https://ssr1.scrape.center/detail/1'
response = requests.get(url)
content = response.content    # 得到网页文本,为字符串
html = etree.HTML(content)    # 使用HTML类将其初始化为XPath解析对象
title = html.xpath('//h2[@class="m-b-sm"]/text()')    # 才可以使用xpath方法
print(title)

3.1.3 XPath的使用

(1)属性匹配和获取一个属性值节点的内容 

html.path() 方法可以根据 () 中的规则,得到对应内容,返回列表。在 xpath 方法中,开头的 // 表示查询内容中所有的h2节点。其他常用规则如下图。

        其之后的[ ]表示h2这个节点中的属性,@class即查询class这个属性=“ ”的节点,即属性匹配。

        /text() 表示获取符合规则节点中的内容(参考上下文代码理解)。所以分析网页的html代码得到上面的规则,然后获取信息。

练习:获取种类、信息、剧情简介、分数

等等。

(2)属性多值匹配

        例如:要获取分数 9.5。其中class中不只有score,难道全写上去?其实使用contains方法即可。

代码如下:

from lxml import etree
import requests

url = 'https://ssr1.scrape.center/detail/1'
response = requests.get(url)
content = response.content
html = etree.HTML(content)
title = html.xpath('//h2[@class="m-b-sm"]/text()')
categories = html.xpath('//div[@class="categories"]/button/span/text()')
info = html.xpath('//div[@class="m-v-sm info"]/span/text()')
drama = html.xpath('//div[@class="drama"]/p/text()')
score = html.xpath('//p[contains(@class, "score")]/text()')

print(title)
print(categories)
print(info)
print(drama)
print(score)

结果如下:

(3)获取<>中的内容

        这里以获取下面文本中的href中的内容为例。

from lxml import etree


text = '''
    <a data-v-7f856186="" href="/detail/11" class="name">
                <h2 data-v-7f856186="" class="m-b-sm">V字仇杀队 - V for Vendetta</h2>
              </a>
'''
html = etree.HTML(text)
result = html.xpath('//a/@href')
print(result)
# 输出:['/detail/11']

(4)多属性匹配

        要获取text中的霸王别姬电影名。使用运算符即可。

from lxml import etree

text = '''
    <h2 class="h2 m-b-sm" name="title">霸王别姬 - Farewell My Concubine</h2>
    <h2 class="h2 m-b-sm">这个杀手不太冷 - Léon</h2>
    <h2 name="title">这个杀手不太冷 - Léon</h2>
'''
html = etree.HTML(text)
result = html.xpath('//h2[contains(@class, "h2") and @name="title"]/text()')
print(result)

(5)运算符及其介绍 

(6)按序选择

:获得节点后,又可以对节点进行 .path 解析。若节点为最内层节点,想获取属性或者文本,应用 .path('./@class'),.path('./text()')等,具体参考上述常用规则。

3.1.4 使用 XPath 过程中的问题

(1) 遍历节点时,解析用 // 出现的问题

例如下方想要得到两个 a 节点中的 class 为 title 的节点中的内容:

from lxml import etree

text = '''
<a href="https://movie.douban.com/subject/1292052/" class="">
     <span class="title">肖申克的救赎</span>
     <span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>
     <span class="other">&nbsp;/&nbsp;月黑高飞(港)  /  刺激1995(台)</span>
</a>

<a href="https://movie.douban.com/subject/1291546/" class="">
     <span class="title">霸王别姬</span>
     <span class="other">&nbsp;/&nbsp;再见,我的妾  /  Farewell My Concubine</span>
</a>
'''
html = etree.HTML(text)
a_href = html.xpath('//a')
print(len(a_href))
print(a_href)
for a in a_href:
    title1 = a.xpath('//span[@class="title"]/text()')
    print(title1)

结果如下:

2
[<Element a at 0x1d08d8f0400>, <Element a at 0x1d091055540>]
['肖申克的救赎', '\xa0/\xa0The Shawshank Redemption', '霸王别姬']
['肖申克的救赎', '\xa0/\xa0The Shawshank Redemption', '霸王别姬']

发现结果相同,原来 // 直接选取了所有的 a 节点,换成 ./ 就是从当前节点往子节点解析。结果如下:

2
[<Element a at 0x235de3a1dc0>, <Element a at 0x235de3a2940>]
['肖申克的救赎', '\xa0/\xa0The Shawshank Redemption']
['霸王别姬']

出现的 \xa0 用 replace('\xa0', '') 函数替换即可。

        本人新手,若有错误,欢迎指正;若有疑问,欢迎讨论。若文章对你有用,点个小赞鼓励一下,谢谢,一起加油吧!

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值