html网页解析方法之xPath

1、xPath - XML Path Language(译为“XML路径语言”)

"路径语言"顾名思义一种通过路径查找目标数据的方法。

在使用Linux系统时,有:当前目录(.)、根目录(/)、上个目录(..) 、相对路径、绝对路径等等概念, 在xPath中也。

所以使用xPath时,类似于在Linux文件系统中查找数据.

2、案例 - 获取 豆瓣读书 Top 250 数据

import requests
from lxml import html
import re


headers = {
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,ko;q=0.7",
    "cache-control": "no-cache",
    "pragma": "no-cache",
    "priority": "u=0, i",
    "sec-ch-ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "\"macOS\"",
    "sec-fetch-dest": "document",
    "sec-fetch-mode": "navigate",
    "sec-fetch-site": "none",
    "sec-fetch-user": "?1",
    "upgrade-insecure-requests": "1",
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
}
cookies = {
    "bid": "swKseSGVCNU",
    "douban-fav-remind": "1",
    "ll": "\"118318\"",
    "_vwo_uuid_v2": "D0BF641BCA325F7CD3DCB4C644DA7EE73|728c96cd6ff5ce7aa56198cbda37daeb",
    "viewed": "\"1007305\"",
    "push_noty_num": "0",
    "push_doumail_num": "0",
    "ap_v": "0,6.0"
}
url = "https://book.douban.com/top250"
response = requests.get(url, headers=headers, cookies=cookies)

# 将html文本转化为可操作的 Element 对象。
ht = html.fromstring(response.text)

# 获取书本信息
book_info = ht.xpath("//table")

# 遍历
for item in book_info:
    # 返回 Element
    # print(html.tostring(item, pretty_print=True, encoding='unicode'))
    # 链接
    book_url = item.xpath('.//a[@class="nbg"]/@href')  # 需要使用. 相对路径
    # 书图片
    img = item.xpath('.//img/@src')
    if img:
        book_img = img[0]
    else:
        book_img = "No"
    # print(book_img)
    # 书名
    book_name = item.xpath('.//div[@class="pl2"]/a/@title')
    # 是否可度
    if len(img) > 1:
        is_read = item.xpath('.//img')[1].xpath('.//@title')[0]
    else:
        is_read = "否"
    # 出版信息
    book_info = item.xpath('.//p[@class="pl"]/text()')[0]
    book_author_split = book_info.split("/")
    if len(book_author_split) == 5:
        book_author_info = f"作者: {book_author_split[0]}\n译者:{book_author_split[1]}\n出版社:{book_author_split[2]}\n出版日期:{book_author_split[3]}\n价格:{book_author_split[4]}"
    elif len(book_author_split) == 4:
        book_author_info = f"作者: {book_author_split[0]}\n出版社:{book_author_split[1]}\n出版日期:{book_author_split[2]}\n价格:{book_author_split[3]}"

    # 评价星级 可以使用contains 或者 starts-with 获取动态class值
    book_rating = item.xpath('.//span[contains(@class, "allstar")]/@class')

    book_rating_star = re.findall(r'[^\d+](\d+)', book_rating[0])
    book_rating_star_final = int(book_rating_star[0]) / 10

    # 评价分数
    book_rating_nums = item.xpath('.//span[@class="rating_nums"]/text()')[0]

    # 评价人数
    book_rating_pl = item.xpath('.//span[@class="pl"]/text()')[0]
    pattern = r"[\u4e00-\u9fff0-9]+"  # 匹配中文和数字
    book_rating_pl_final = re.findall(pattern, book_rating_pl)

    # 一句话评价
    book_inq = item.xpath('.//span[@class="inq"]/text()')
    if book_inq:
        book_inq_text = book_inq[0]
    else:
        book_inq_text = "无"

    print(
        f'下钻链接: {book_url[0]}\n书图片:{book_img}\n书名:{book_name}\n是否可试读:{is_read}\n{book_author_info}\n'
        f'星级:{book_rating_star_final}\n评分:{book_rating_nums}\n评论人数:{book_rating_pl_final[0]}\n一句话概括:{book_inq_text}')
    print("\n----------------------")

3、常用方法

与bs4 常用方法find定位关键词相比,xPath使用方法xpath定位关键词.

  • 绝对路径 : 获取 所有的table 标签 
    book_info = ht.xpath("//table")
    
  • 相对路径: 
    book_url = item.xpath('.//a[@class="nbg"]/@href')  # 需要使用. 相对路径
  • 定位标签属性,使用关键词@,也可以用它返回关键词属性
    book_name = item.xpath('.//div[@class="pl2"]/a/@title')
    
获取返回值 有两种方式: 
  • 使用tostring 返回Element 元素; 
  • @返回属性值
  • text() 返回标签文本
  • 获取动态标签值
    可以使用contains 或者 starts-with

4、总结

BeautifulSoup 使用html解释器 与 xPath相比.

  • 语法和使用方式

    • BeautifulSoup:通过面向对象的方式来进行操作,例如 .find().find_all().select()
    • XPath:通过路径表达式来进行查询,例如 /html/body/div//div[@class='class_name']
  • 选择方式

    • BeautifulSoup:主要基于标签名、类名、id 或属性来定位元素,支持直接通过属性进行筛选。
    • XPath:基于路径表达式,支持更复杂的查询,例如选择第一个、最后一个元素,或者基于条件查找元素。
  • 灵活性和复杂查询

    • BeautifulSoup:适合进行简单到中等复杂度的选择,通常通过 .find().find_all() 或 CSS 选择器来完成。对于非常复杂的选择,可能会觉得不够灵活。
    • XPath:适合进行非常复杂的查询,可以使用逻辑表达式、轴、索引等多种方式组合条件,能精确定位到想要的元素。
  • 性能

    • BeautifulSoup:性能在处理小型文档时足够好,但在处理大型文档时会稍慢一些。
    • XPath:在大规模数据查询时通常更高效,尤其是在 lxml 配合使用时。
  • 错误容忍

    • BeautifulSoup:非常容错,可以处理不规范的 HTML 标签(如缺少结束标签、不闭合标签等)。
    • XPath:要求文档符合标准 XML 或 HTML 规范,否则查询会失败。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值