You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用html.parser获取div标签内的目标价格信息?

解决HTML中获取span标签后文本价格的问题

你是不是头疼怎么拿到<div class='card-product__price'>里,那个旧价格span后面的目标价格?现在你的HTMLParser代码输出空值,咱们先找找问题出在哪,再给你搞定它。

先说说你现有代码的问题

  • 目标div的class匹配错了:你代码里判断的是card-product__details,但实际要找的div class是card-product__price,这第一步就没命中目标!
  • 没有跟踪span标签的状态:目标价格是span的兄弟文本节点,你的代码没标记“已经过了旧价格span”这个状态,自然不知道什么时候该抓取后续的文本。
  • 触发条件逻辑有问题:self.is_price_field的触发条件不明确,导致handle_data里的判断一直不成立,根本不会去处理数据。

方案一:修正原生HTMLParser代码

如果一定要用HTMLParser,咱们调整逻辑,跟踪进入目标div、经过span的状态,再抓取文本:

from html.parser import HTMLParser
import re

class PriceParser(HTMLParser):
    def __init__(self):
        super().__init__()
        self.in_target_div = False  # 是否进入了目标价格div
        self.span_passed = False    # 是否已经跳过了旧价格span
        self.target_price = None    # 存储最终价格

    def handle_starttag(self, tag, attrs):
        # 检查是否进入目标div
        if tag == 'div':
            attrs_dict = dict(attrs)
            if attrs_dict.get('class') == 'card-product__price':
                self.in_target_div = True
        # 如果在目标div里,检查是否是旧价格span
        elif self.in_target_div and tag == 'span':
            attrs_dict = dict(attrs)
            if attrs_dict.get('class') == 'card-product__price-old':
                self.span_passed = True  # 标记已经遇到这个span

    def handle_endtag(self, tag):
        # 离开目标div时重置状态
        if tag == 'div' and self.in_target_div:
            self.in_target_div = False
            self.span_passed = False

    def handle_data(self, data):
        # 只有满足三个条件才处理:在目标div、已过span、还没拿到价格
        if self.in_target_div and self.span_passed and self.target_price is None:
            cleaned_text = data.strip()
            if cleaned_text:  # 过滤掉纯空白的文本(比如换行、空格)
                # 清理掉非数字和小数点的字符,保留价格数值
                self.target_price = re.sub('[^\d.]', '', cleaned_text)

# 测试使用
html = '''
<div class='card-product__price'>
    <span class='card-product__price-old'>Old price is here</span>
        '199.99'
</div>
'''

parser = PriceParser()
parser.feed(html)
print(parser.target_price)  # 输出: 199.99

方案二:用BeautifulSoup更省心

原生HTMLParser写起来太繁琐了,推荐用BeautifulSoup,几行代码就能搞定:

from bs4 import BeautifulSoup
import re

html = '''
<div class='card-product__price'>
    <span class='card-product__price-old'>Old price is here</span>
        '199.99'
</div>
'''

soup = BeautifulSoup(html, 'html.parser')
# 找到目标div和里面的旧价格span
price_div = soup.find('div', class_='card-product__price')
old_price_span = price_div.find('span', class_='card-product__price-old')
# 获取span的下一个兄弟文本节点,清理空白和无关字符
target_text = old_price_span.next_sibling.strip()
cleaned_price = re.sub('[^\d.]', '', target_text)

print(cleaned_price)  # 输出: 199.99

这个方法里,next_sibling直接定位到span后面的文本节点,省去了复杂的状态跟踪,代码简洁太多。

内容的提问来源于stack exchange,提问作者Beginner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 10:22:54