如何使用BeautifulSoup库来提取HTML中的特定元素

前言

爬虫拿到HTML源码之后,最核心的工作就是提取特定元素、文本、链接 。BeautifulSoup4(bs4)提供多种方式定位页面标签:标签名搜索、class/id匹配、属性过滤、CSS选择器。CSS选择器select()/select_one()日常开发用得最多,写法简洁直观。

前置依赖

复制代码
pip install beautifulsoup4 lxml

from bs4 import BeautifulSoup

html_sample = """
<div class="table-wrap">
    <div class="item row">
        <div class="title">标准编号:GB50017‑2003</div>
        <div class="type">国家标准</div>
        <a href="/detail?id=1001" class="link">查看详情</a>
    </div>
    <div class="item row">
        <div class="title">标准编号:GB50405‑2007</div>
        <div class="type">国家标准</div>
        <a href="/detail?id=1002" class="link">查看详情</a>
    </div>
</div>
"""
# 加载HTML文档
soup = BeautifulSoup(html_sample, "lxml")

1. find():提取第一个匹配的元素

find(标签名, 属性条件),找到第一个匹配节点,找不到返回None,不会抛异常。

复制代码
# 查找第一个class="item row"的div节点
tag = soup.find("div", class_="item row")
if tag:
    print(tag.get_text(strip=True))

# 根据id查找
soup.find(id="table-wrap")

# 根据自定义属性过滤,比如 data‑xxx
soup.find("a", attrs={"class":"link"})

⚠️注意:class是Python关键字,参数要写class_=,末尾带下划线。

2. find_all():提取全部匹配元素,返回列表

返回所有符合条件节点组成的列表,没有匹配返回空列表[]。

复制代码
# 获取全部 class="item row" 的div
item_list = soup.find_all("div", class_="item row")
for item in item_list:
    text = item.get_text(strip=True)
    print(text)

# 限制返回数量,只取前1条
item_list = soup.find_all("div", class_="item row", limit=1)

3. CSS选择器 select / select_one(最推荐)

select_one():匹配第一个 ,无结果返回None

select():匹配全部,返回节点列表

语法和网页CSS完全一致:

  • .类名 → class筛选

  • #id值 → id筛选

  • 标签名 → 标签筛选

  • 父标签 > 子标签 → 直接子元素

  • 父标签 子标签 → 后代所有子元素

    取第一个 .item.row

    first_item = soup.select_one(".item.row")

    获取全部 .item.row

    all_items = soup.select(".item.row")

    获取 .item 下面所有a标签

    link_tags = soup.select(".item.row a.link")

    直接子元素 >

    title_div = soup.select_one(".item.row > .title")

4. 拿到元素之后:提取文本、属性

提取文本

复制代码
tag = soup.select_one(".title")

# get_text() 推荐,支持参数控制
text1 = tag.get_text(strip=True)          # 去除前后换行空格
text2 = tag.get_text(strip=True, separator=" ") # 子节点文本用空格隔开

# 不推荐 .text ,无法做strip处理
# text = tag.text

提取标签属性(href、src、style等)

优先使用.get(),属性不存在返回None,不会抛出KeyError

复制代码
a_tag = soup.select_one("a.link")
href = a_tag.get("href")   # ✅ 安全,无属性返回None

# 不推荐直接下标取值,没有属性直接报错
# href = a_tag["href"]

# 获取全部属性字典
attr = a_tag.attrs
print(attr)

5. 实战示例:循环提取多条列表数据

以上面示例html,循环取出每条的标题、类型、链接:

复制代码
item_list = soup.select(".item.row")
result = []
for item in item_list:
    title = item.select_one(".title").get_text(strip=True)
    std_type = item.select_one(".type").get_text(strip=True)
    link = item.select_one(".link").get("href")
    result.append({
        "title": title,
        "std_type": std_type,
        "link": link
    })
print(result)

6. 结合requests网页真实场景

复制代码
import requests
from bs4 import BeautifulSoup

resp = requests.get("[https://example.com](https://example.com)")
soup = BeautifulSoup(resp.text, "lxml")

# 提取页面所有a标签链接
for a in soup.select("a"):
    url = a.get("href")
    print(url)

7. 常见踩坑点

  1. 判空! find() / select_one() 找不到返回None,直接调用.get_text()会报AttributeError。

    tag = soup.select_one(".not‑exist")
    if tag is not None:
    txt = tag.get_text(strip=True)

  2. class有多个值时:class="item row",bs4中class_="item row"可以匹配;CSS选择器写.item.row(中间无空格)。

  3. 不要用正则去解析HTML,标签嵌套、属性顺序变化,正则极易失效。

  4. select()永远返回列表,哪怕只有一条数据,需要用下标[0]或者改用select_one()。

  5. 网页残缺、标签不闭合,lxml解析器容错能力强,优先使用。

find/find_all 和 select/select_one怎么选

方式 优点 缺点
find / find_all 原生API,支持复杂属性过滤 写多层嵌套比较繁琐
select / select_one CSS选择器,写法简短,前端开发易上手 部分复杂属性匹配不如find灵活

日常爬虫开发优先使用select、select_one。

相关推荐
专注API从业者5 分钟前
告别复杂页面解析,OpenClaw 快速搭建电商商品监控与数据分析脚本
大数据·数据库·python·数据挖掘·数据分析
王立志_LEO30 分钟前
HTTPX 完整用法总结
python
ggb喔33 分钟前
52pojie 的图片工具:为什么无损转换后体积涨了 6 倍、照片方向还是歪的
图像处理·python·算法·计算机视觉·图形渲染·媒体
hnxaoli33 分钟前
win10小程序(二十三)新建带时间文件夹
python
企业数字化笔记40 分钟前
AI工具参数很多怎么办?预设、表单校验、危险参数与配置审计
java·spring boot·python·音视频
2601_962885721 小时前
如何用 Python 计算 BBI 多空指标?
开发语言·python
必须得开心呀1 小时前
为什么 python-docx 打不开加密的 .docx,Word COM 却能打开
python·word
VidDown2 小时前
上传 2GB 文件别让 Django 接:分片上传、对象存储直传与秒传
python·django·音视频·状态模式·实时音视频·视频编解码·视频
打工仔折腾 AI2 小时前
FaceFusion本地换脸实战:Windows整合包、模型选择与遮罩调参记录
人工智能·windows·后端·python·深度学习·性能优化·ai agent 实战
yi0112 小时前
DAY24: LeetCode 167:两数之和 II|从暴力枚举到左右双指针
笔记·python·算法·leetcode·二分查找·双指针