如何使用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。

相关推荐
锋行天下8 小时前
Langgraph HITL 中断运行,用户输入后输出打字效果
人工智能·python
时早玖沐8 小时前
给 AstrBot 写一个天气推送插件:12 次提交、6 个坑
python·开源·ai编程
触底反弹8 小时前
🚀 FastAPI 五大重难点深度剖析:从 500 报错到彻底搞懂 Depends、Pydantic 与 SQLAlchemy
python·fastapi
cpolar技术支持8 小时前
网关加 gzip,同时开启 chunked,下载回来的包解不开:把两层编码的解压顺序与长度核对做成只读页
python·http·网络编程·socket·内网穿透
小嘉丶学长8 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
迪菲赫尔曼8 小时前
【基础篇 11】把官方源码放到服务器:版本、解压层级和安装位置,一次弄清楚
运维·服务器·开发语言·人工智能·python·yolo·目标检测
用户8356290780518 小时前
Python 调整 Excel 工作表显示设置
后端·python
小咕聊编程9 小时前
教育大数据可视化系统
python·django·flask
lusklusklusk9 小时前
Python 巡检脚本:进程运行状态、数据库写入时效检查及邮件通知与告警
数据库·python·oracle
Angeldream1239 小时前
第 10 章 医学影像伦理与安全
图像处理·人工智能·python·安全·机器学习·医学影像