讲师中心 微信公众号
AI工具推荐 视频效率加速

Python BeautifulSoup:从复杂HTML元素中精准提取数值

云涛吖_5965

云涛吖_5965

发布时间:2025-09-26 13:53:00

|

973人浏览过

|

来源于php中文网

原创

Python BeautifulSoup:从复杂HTML元素中精准提取数值

本文旨在指导读者如何使用Python的BeautifulSoup库从复杂的HTML结构中准确提取数值,特别是当目标元素包含注释、货币符号或其他非数字字符时。文章将探讨div.text的基本用法,并提供处理实际网页抓取中可能遇到的多种情况的鲁棒性策略,包括检查元素存在性、过滤非数字字符以及适应不同的HTML结构,以确保提取数据的准确性和代码的稳定性。

引言:HTML文本提取的挑战

在进行网页抓取(web scraping)时,我们经常需要从html页面中提取特定的文本信息,例如商品价格、产品名称等。然而,实际的html结构往往比我们想象的要复杂。目标文本可能被包裹在带有特殊字符(如货币符号)、html注释()甚至是空白标签的元素中。例如,从以下html片段中提取纯数字“5”:

<div class="DrugPriceBox__price___dj2lv">₹<!-- -->5</div>

直接使用BeautifulSoup的text属性有时会包含不必要的字符,或者在特定情况下,如果元素未正确找到,甚至可能导致程序错误。因此,掌握鲁棒的文本提取和清洗方法至关重要。

BeautifulSoup text 属性基础

BeautifulSoup库在处理HTML时,element.text属性是一个非常方便的工具,它会递归地获取一个标签及其所有子孙标签中的文本内容,并将它们连接成一个字符串。对于上述示例,即使中间存在一个HTML注释,div.text通常也能正确地聚合文本内容。

from bs4 import BeautifulSoup

html_doc = '<div class="DrugPriceBox__price___dj2lv">₹<!-- -->5</div>'
soup = BeautifulSoup(html_doc, 'html.parser')

div_tag = soup.find('div', class_='DrugPriceBox__price___dj2lv')
if div_tag:
    print(f"原始文本: {div_tag.text}") # 输出: 原始文本: ₹5
else:
    print("未找到目标div标签。")

从上述输出可以看出,div.text成功地提取了“₹5”。然而,我们的目标通常是纯粹的数字“5”,这就需要进一步的数据清洗。

构建鲁棒的网页抓取器

为了在实际的网页抓取任务中更稳定、更准确地提取数据,我们需要考虑以下几个方面:

立即学习“Python免费学习笔记(深入)”;

1. 发送HTTP请求与请求头

直接访问网页时,许多网站会检查请求的User-Agent头信息,以识别请求来源是浏览器还是自动化脚本。为避免被网站阻断,建议在requests请求中模拟浏览器行为。

Java Api Extractor
Java Api Extractor

从 Java 项目中提取 Controller 层接口定义为 JSON 数据。

下载
import requests

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124124 Safari/537.36'
}
# requests.get(url, headers=headers)

2. 元素查找与存在性检查

soup.find()或soup.select_one()方法在未找到匹配元素时会返回None。在尝试访问None对象的属性(如.text)时,程序会抛出AttributeError。因此,在提取文本之前,务必检查找到的元素是否为None。

# ... (soup已创建)
element = soup.find('div', class_='some-class')
if element:
    # 安全地访问element.text
    text_content = element.text
else:
    print("目标元素未找到。")

3. 处理多种HTML结构

网站的HTML结构可能因A/B测试、版本更新或不同页面类型而有所不同。一个健壮的抓取器应该能够适应这些变化,尝试查找多种可能的元素结构。例如,价格信息可能有时在div中,有时在span中,且类名可能不同。

# 尝试查找第一种结构
element1 = soup.find('div', class_='class-A')
if element1:
    price_text = element1.text
else:
    # 如果第一种结构未找到,尝试查找第二种结构
    element2 = soup.find('span', class_='class-B')
    if element2:
        price_text = element2.text
    else:
        price_text = "未找到价格信息"

4. 提取与清洗数值

获取到原始文本后,通常需要进一步清洗以提取纯粹的数字。这包括移除货币符号、空白字符以及任何非数字字符。可以使用Python的字符串方法结合isdigit()或正则表达式来实现。

import string

raw_price_text = "₹5.50" # 假设从element.text获得
acceptable_chars = set(string.digits + '.') # 允许数字和小数点
cleaned_price = ''.join(char for char in raw_price_text if char in acceptable_chars)
print(f"清洗后的价格: {cleaned_price}") # 输出: 清洗后的价格: 5.50

完整示例代码

下面是一个结合了上述所有最佳实践的完整示例,用于从指定URL的网页中提取药品价格,并处理多种HTML结构和数据清洗:

import requests
from bs4 import BeautifulSoup
import string

# 定义请求头,模拟浏览器访问
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124124 Safari/537.36'
}

def extract_price_from_url(url):
    """
    从指定URL的网页中提取药品价格。
    尝试多种HTML结构并过滤非数字字符。
    """
    try:
        # 发送HTTP请求并检查响应状态
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()  # 如果状态码不是200,则抛出HTTPError异常
    except requests.exceptions.RequestException as e:
        print(f"请求URL失败: {url}, 错误: {e}")
        return None

    # 使用BeautifulSoup解析HTML内容
    soup = BeautifulSoup(response.content, "html.parser")
    price_text = None

    # 尝试第一种div标签的定价格式
    div_price_box = soup.find('div', class_='DrugPriceBox__price___dj2lv')
    if div_price_box:
        price_text = div_price_box.text
    else:
        # 如果div格式未找到,尝试第二种span标签的定价格式
        # 注意:这里的类名来源于实际网页结构分析
        span_price_box = soup.find('span', class_="PriceBoxPlanOption__margin-right-4___2aqFt PriceBoxPlanOption__stike___pDQVN")
        if span_price_box:
            price_text = span_price_box.text

    if price_text:
        # 过滤非数字字符,只保留数字和小数点,以便转换为浮点数
        acceptable_chars = set(string.digits + '.')
        cleaned_price = ''.join(char for char in price_text if char in acceptable_chars)
        return cleaned_price
    else:
        return "未找到价格"

if __name__ == '__main__':
    # 示例URL,第一个URL对应div格式,第二个对应span格式
    url1 = 'https://www.1mg.com/drugs/acticort-5mg-tablet-321932'
    url2 = 'https://www.1mg.com/drugs/zerodol-sp-tablet-67307'

    print(f"从 {url1} 提取价格:")
    price1 = extract_price_from_url(url1)
    print(f"提取到的价格: {price1}")

    print(f"\n从 {url2} 提取价格:")
    price2 = extract_price_from_url(url2)
    print(f"提取到的价格: {price2}")

    # 假设一个不存在价格信息的页面
    url_no_price = 'https://www.example.com'
    print(f"\n从 {url_no_price} 提取价格:")
    price_no_price = extract_price_from_url(url_no_price)
    print(f"提取到的价格: {price_no_price}")

注意事项与最佳实践

  • 动态内容(JavaScript渲染): 如果目标数据是通过JavaScript在页面加载后动态生成的,BeautifulSoup将无法直接获取。此时,需要使用Selenium等工具来模拟浏览器行为,等待JavaScript执行完毕后再抓取内容。
  • 网站结构变化: 网页结构并非一成不变。网站更新可能导致类名、ID或标签结构发生变化,从而使抓取代码失效。定期检查并更新抓取逻辑是必要的。
  • 反爬机制: 频繁或异常的请求可能会触发网站的反爬机制,导致IP被封禁、出现验证码或返回错误信息。可以考虑使用代理IP池、设置请求延迟、限制请求频率等策略。
  • 合法合规: 在进行网页抓取前,务必查阅网站的robots.txt文件,了解允许抓取的范围。同时,遵守当地法律法规,尊重网站所有者的权益,避免对网站服务器造成过大负担。

总结

通过本文的介绍,我们学习了如何使用Python的BeautifulSoup库从包含特殊字符或注释的HTML元素中准确提取数值。关键在于理解element.text的工作原理,并通过引入请求头、进行元素存在性检查、适应多种HTML结构以及对提取到的文本进行清洗,来构建一个鲁棒且高效的网页抓取解决方案。遵循这些最佳实践,将大大提高您在实际网页抓取项目中的成功率和代码的稳定性。

相关文章

HTML速学教程(入门课程)
HTML速学教程(入门课程)

HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

4616

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

3121

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

8682

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

812

2023.08.11

正则表达式空格
正则表达式空格

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。本专题为大家提供正则表达式相关的文章、下载、课程内容,供大家免费下载体验。

520

2023.08.31

Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

693

2023.11.13

正则表达式空格如何表示
正则表达式空格如何表示

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。想了解更多正则表达式空格怎么表示的内容,可以访问下面的文章。

406

2023.11.17

正则表达式中如何匹配数字
正则表达式中如何匹配数字

正则表达式中可以通过匹配单个数字、匹配多个数字、匹配固定长度的数字、匹配整数和小数、匹配负数和匹配科学计数法表示的数字的方法匹配数字。更多关于正则表达式的相关知识详情请看本专题下面的文章。php中文网欢迎大家前来学习。

719

2023.12.06

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebStorm 官方调试文档
WebStorm 官方调试文档

共0课时 | 0人学习

React 教程
React 教程

共58课时 | 12.4万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 6.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn