Python使用BeautifulSoup抓取和解析网页数据的入门教程

 更新时间:2026年05月13日 08:49:19   作者:yuanpan  
文章介绍了Python中BeautifulSoup库用于解析HTML和提取网页数据的基本使用方法,包括安装依赖、基础用法、常用API以及实际操作示例,文中详细解释了BeautifulSoup与requests的关系,如何抓取和解析网页数据,并提供了常见错误和注意事项,需要的朋友可以参考下

很多 Python 初学者学完基础语法之后,都会很自然地遇到一个问题:

我能不能把网页里的内容提取下来,变成自己能处理的数据?

比如:

  • 抓取文章标题
  • 提取商品名称和价格
  • 收集招聘信息
  • 批量整理博客链接
  • 分析网页中的表格和列表

这时候,BeautifulSoup 往往就是最适合入门的工具之一。

它不像大型爬虫框架那样一上来就有很多工程化概念,也不像正则表达式那样容易把人绕晕。它做的事情很纯粹:

帮你解析 HTML,然后从中提取你真正需要的数据。

如果你现在正在学习 Python,又想快速上手网页数据抓取,这篇文章会非常适合你。我们会从 0 开始讲清楚:

  • BeautifulSoup 到底是什么
  • 它和 requests 是什么关系
  • 如何抓取网页 HTML
  • 如何用 find()find_all()select() 提取数据
  • 如何写出一个完整的小型抓取脚本
  • 实际使用时有哪些坑要提前避开

1. BeautifulSoup 是什么

BeautifulSoup 是一个专门用来解析 HTML / XML 文档的 Python 库。

你可以把它理解成一个“网页内容整理器”。

网页源码本来是一大段字符串,里面夹杂了很多标签,比如:

<div class="article">
  <h2>Python 入门</h2>
  <a href="/post/1" rel="external nofollow"  rel="external nofollow" >查看详情</a>
</div>

如果你直接拿字符串去切片、用正则硬抠,代码会非常脆弱。

而 BeautifulSoup 会先把这段 HTML 解析成一个结构化对象,然后你就可以像查树节点一样去找:

  • 某个标签
  • 某个 class
  • 某个 id
  • 某个属性
  • 某个标签里的文本

这也是它名字里 Soup 的感觉所在。原本很乱的网页源码,会被它整理成更容易“舀出来”的结构。

2. BeautifulSoup 和 requests 是什么关系

很多新手刚接触网页抓取时,最容易混淆这两个库。

其实职责非常清楚:

  • requests:负责向网站发请求,把网页内容下载回来
  • BeautifulSoup:负责解析网页内容,并从中提取数据

所以它们常常一起出现:

  1. 先用 requests.get() 拿到 HTML
  2. 再用 BeautifulSoup() 把 HTML 解析成对象
  3. 最后用各种选择器提取需要的数据

一句话记住:

requests 管“拿网页”,BeautifulSoup 管“拆网页”。

3. 先安装依赖

直接安装 BeautifulSoup:

pip install beautifulsoup4

实际抓取网页时,通常还会配合 requests

pip install requests beautifulsoup4

如果你后面想让解析速度更快,也可以安装 lxml 作为解析器:

pip install lxml

不过对初学者来说,先用 Python 自带的 html.parser 就够了。

4. BeautifulSoup 最基础的使用方式

先不要急着抓真实网站,先用一段本地 HTML 练手,这样最容易理解。

from bs4 import BeautifulSoup


html = """
<html>
  <body>
    <h1>Python 学习笔记</h1>
    <p class="desc">这是一个 BeautifulSoup 示例页面</p>
    <a href="/post/1" rel="external nofollow"  rel="external nofollow" >第一篇文章</a>
    <a href="/post/2" rel="external nofollow" >第二篇文章</a>
  </body>
</html>
"""

soup = BeautifulSoup(html, "html.parser")

print(soup.h1.get_text())
print(soup.find("p", class_="desc").get_text())

这段代码里最关键的是:

soup = BeautifulSoup(html, "html.parser")

它表示把字符串形式的 HTML 交给 BeautifulSoup 解析。

后面你就可以通过 soup.h1find()select() 这些方式去拿数据。

5. 先掌握最常用的 4 个操作

BeautifulSoup 的 API 不算少,但对于新手来说,真正最常用的就这几个。

5.1find():找第一个匹配标签

title = soup.find("h1")
print(title.get_text())

如果页面里有多个 h1,它只会返回第一个匹配项。

你也可以加属性条件:

desc = soup.find("p", class_="desc")

注意这里是 class_,后面要加下划线,因为 class 是 Python 关键字。

5.2find_all():找所有匹配标签

links = soup.find_all("a")
for link in links:
    print(link.get_text(), link.get("href"))

这个方法非常适合提取列表数据,比如:

  • 所有文章链接
  • 所有商品卡片
  • 所有招聘项

5.3select():用 CSS 选择器查找

如果你有一点前端基础,会非常喜欢这个方法。

items = soup.select("a")
desc = soup.select_one("p.desc")

常见写法:

  • div:选所有 div
  • .card:选 class 为 card 的元素
  • #main:选 id 为 main 的元素
  • .article-list a:选某个区域下面的所有链接

在很多实际项目中,select()select_one() 会比 find() 更顺手。

5.4get_text()和get()

提取文本:

text = title.get_text(strip=True)

提取属性:

href = link.get("href")

这里要区分清楚:

  • get_text():拿标签里的文字
  • get("href"):拿标签属性

6. 写一个稍微像样一点的解析示例

下面这段示例会更接近真实项目。

我已经把完整代码整理成单独文件,方便你本地直接运行:

beautifulsoup_web_scraping_demo.py

代码如下:

from __future__ import annotations

from bs4 import BeautifulSoup
import requests


SAMPLE_HTML = """
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <title>BeautifulSoup Demo</title>
</head>
<body>
    <div class="article-list">
        <article class="article-card" data-id="101">
            <h2 class="title"><a href="/post/101" rel="external nofollow" >Python 抓取网页入门</a></h2>
            <span class="author">小明</span>
            <span class="views">1280</span>
        </article>
        <article class="article-card" data-id="102">
            <h2 class="title"><a href="/post/102" rel="external nofollow" >BeautifulSoup 选择器快速上手</a></h2>
            <span class="author">小红</span>
            <span class="views">980</span>
        </article>
        <article class="article-card" data-id="103">
            <h2 class="title"><a href="/post/103" rel="external nofollow" >requests 和 bs4 配合实战</a></h2>
            <span class="author">小李</span>
            <span class="views">1560</span>
        </article>
    </div>
</body>
</html>
"""


def parse_local_html() -> list[dict[str, str]]:
    soup = BeautifulSoup(SAMPLE_HTML, "html.parser")
    articles: list[dict[str, str]] = []

    for card in soup.select(".article-card"):
        link = card.select_one(".title a")
        author = card.select_one(".author")
        views = card.select_one(".views")

        if link is None or author is None or views is None:
            continue

        articles.append(
            {
                "id": card.get("data-id", ""),
                "title": link.get_text(strip=True),
                "url": link.get("href", ""),
                "author": author.get_text(strip=True),
                "views": views.get_text(strip=True),
            }
        )

    return articles


def fetch_page_title(url: str) -> str:
    headers = {
        "User-Agent": (
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/124.0 Safari/537.36"
        )
    }
    response = requests.get(url, headers=headers, timeout=10)
    response.raise_for_status()

    soup = BeautifulSoup(response.text, "html.parser")
    if soup.title and soup.title.string:
        return soup.title.string.strip()
    return "页面没有 title"


def main() -> None:
    print("本地 HTML 解析结果:")
    for item in parse_local_html():
        print(item)

    # 真实抓取时,把这里替换成你自己的目标网页。
    # 使用前请先确认目标站点允许抓取,并控制请求频率。
    # title = fetch_page_title("https://example.com")
    # print("页面标题:", title)


if __name__ == "__main__":
    main()

这个示例故意分成两部分:

  • parse_local_html():先教你专注理解 BeautifulSoup 的解析过程
  • fetch_page_title():再告诉你如何把真实网页抓下来后交给 BeautifulSoup

学习这类东西时,建议你也这么练:

先会“解析”,再会“抓取”,最后再把两者组合。

7. 真实抓取网页时的标准流程

很多网站的抓取逻辑,本质上都可以拆成下面这几步:

第一步:发送请求

import requests

response = requests.get(url, timeout=10)
html = response.text

第二步:构造 BeautifulSoup 对象

from bs4 import BeautifulSoup

soup = BeautifulSoup(html, "html.parser")

第三步:定位数据区域

cards = soup.select(".article-card")

第四步:从每个区域中提取字段

for card in cards:
    title = card.select_one(".title").get_text(strip=True)
    link = card.select_one("a").get("href")

第五步:整理成结构化数据

data.append({
    "title": title,
    "url": link,
})

所以你会发现,BeautifulSoup 真正的核心工作其实是:

先找到“每条数据的边界”,再从每条记录里拆字段。

这也是写抓取脚本时最重要的思维方式。

8. 新手最常见的一个误区:一上来就抓整页

刚开始学网页抓取时,很多人喜欢一上来就对整页所有标签乱搜。

例如页面里有几十个 a 标签,你直接:

soup.find_all("a")

当然能找到一堆链接,但里面往往混着:

  • 导航栏链接
  • 广告链接
  • 相关文章链接
  • 正文链接
  • 页脚链接

最后数据会很乱。

更好的做法是:

  1. 先找到列表区域
  2. 再在这个区域里找标题、链接、作者、时间

也就是说,尽量从:

soup.select(".article-card")

这种“按块定位”的方式入手,而不是全页面乱抓。

9. BeautifulSoup 常见解析器怎么选

创建对象时你会看到第二个参数:

BeautifulSoup(html, "html.parser")

这里指定的是解析器。

常见的有三个:

  • html.parser:Python 自带,安装最省事
  • lxml:速度通常更快,项目里很常用
  • html5lib:容错更强,但一般更重

如果你是初学者:

  • 学习阶段先用 html.parser
  • 后面项目里再考虑 lxml

先跑通流程,比一开始纠结性能更重要。

10. 为什么有时抓不到你在浏览器里看到的内容

这是 BeautifulSoup 初学者非常容易遇到的坑。

你在浏览器里明明看到了内容,但 requests.get() 拿回来的 HTML 里却没有。

原因通常是:

页面的数据是通过 JavaScript 动态加载的。

也就是说,浏览器打开页面后,还会继续执行 JS,再向接口请求数据,最后才把内容渲染出来。

requests 拿到的只是最初的 HTML。

这时候 BeautifulSoup 没问题,问题在于你抓到的输入源就不完整。

遇到这种情况,常见思路有两个:

  • 直接分析网页接口,改抓接口返回的 JSON
  • 使用 Playwright、Selenium 这类浏览器自动化工具

所以要记住:

BeautifulSoup 擅长解析 HTML,但它不会替你执行前端 JavaScript。

11. 实战中必须注意的几个问题

这部分比语法更重要。

11.1 不要把网页抓取理解成“复制粘贴源码”

真正的抓取工作,不是看到标签就抄代码,而是要先观察页面结构:

  • 每条数据的容器是什么
  • 标题在哪个标签
  • 链接在哪个属性
  • 时间、作者、价格是否都在固定位置

只有先分析结构,BeautifulSoup 才会变得好用。

11.2 记得加请求头

有些网站对默认请求不友好,最简单的处理就是带一个常见浏览器的 User-Agent

headers = {
    "User-Agent": "Mozilla/5.0 ..."
}
response = requests.get(url, headers=headers, timeout=10)

11.3 记得处理异常

不要默认所有请求都会成功。

response.raise_for_status()

至少先把 HTTP 错误暴露出来,否则你很可能在拿一个报错页做解析。

11.4 控制抓取频率

如果你需要抓取多页内容,不要用极高频率连续请求。

这不仅容易失败,也可能给目标网站带来压力。

11.5 尊重站点规则和数据边界

在使用 BeautifulSoup 抓取网页数据前,应该先确认目标站点的使用条款、robots 规则以及数据使用边界。

技术上能抓,不代表业务上就一定适合抓。

12. BeautifulSoup 适合哪些场景

BeautifulSoup 非常适合下面这些任务:

  • 网页结构比较稳定
  • 页面主要内容就在 HTML 中
  • 抓取规模不算特别大
  • 想快速写一个轻量脚本
  • 想先验证网页数据能不能提取

比如:

  • 文章列表抓取
  • 简单商品页抓取
  • 博客导航页整理
  • 表格数据提取
  • 页面链接分析

如果你只是想先把网页数据提下来,再做后续分析处理,BeautifulSoup 是一个很好的起点。

13. BeautifulSoup 和 Scrapy 该怎么选

这个问题很多人都会问。

可以这样理解:

  • BeautifulSoup 更像“解析工具”
  • Scrapy 更像“完整爬虫框架”

如果你的需求是:

  • 抓 1 个到几十个页面
  • 快速写脚本验证
  • 重点在网页解析本身

那么 requests + BeautifulSoup 会更轻、更直接。

如果你的需求是:

  • 大量分页抓取
  • 自动跟进链接
  • 需要统一导出、调度、去重、重试

那通常就要考虑 Scrapy 了。

所以 BeautifulSoup 并不是“低配版 Scrapy”,而是更适合入门和轻量场景的工具。

14. 给初学者的学习建议

如果你想真正学会 BeautifulSoup,不建议只看语法。

更好的学习顺序是:

  1. 先用本地 HTML 字符串练 find()find_all()select()
  2. 再学 requests.get() 把网页拿下来
  3. 再自己挑一个结构简单的页面练手
  4. 把提取结果整理成字典或列表
  5. 最后导出成 JSON、CSV 或写入数据库

你会发现,真正的能力不是“会几个 API”,而是:

看到一个网页,能快速判断该从哪里切入提取数据。

15. 总结

BeautifulSoup 是 Python 生态里非常经典、也非常适合新手入门的网页解析库。

它最大的价值不是“语法多高级”,而是把网页提取这件事变得直观了很多。

记住这套组合最核心的分工:

  • requests:负责抓网页
  • BeautifulSoup:负责拆网页
  • 你的 Python 代码:负责整理数据和后续处理

如果你正在学习 Python,又希望尽快做出一些“能解决实际问题”的小工具,那么 BeautifulSoup 非常值得你亲手写一遍。

先从本地 HTML 开始,跑通选择器,再去抓真实网页,你的进步会快很多。

以上就是Python使用BeautifulSoup抓取和解析网页数据的入门教程的详细内容,更多关于Python BeautifulSoup抓取和解析网页数据的资料请关注脚本之家其它相关文章!

相关文章

  • Python+Pandas 获取数据库并加入DataFrame的实例

    Python+Pandas 获取数据库并加入DataFrame的实例

    今天小编就为大家分享一篇Python+Pandas 获取数据库并加入DataFrame的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • python中List的sort方法指南

    python中List的sort方法指南

    我们需要对List进行排序,Python提供了两个方法:1.用List的成员函数sort进行排序;2.用built-in函数sorted进行排序,今天我们就来探讨下这2个方法
    2014-09-09
  • Python 利用scrapy爬虫通过短短50行代码下载整站短视频

    Python 利用scrapy爬虫通过短短50行代码下载整站短视频

    近日,有朋友向我求助一件小事儿,他在一个短视频app上看到一个好玩儿的段子,想下载下来,可死活找不到下载的方法。经过我的一番研究才找到解决方法,下面小编给大家分享Python 利用scrapy爬虫通过短短50行代码下载整站短视频的方法,感兴趣的朋友一起看看吧
    2018-10-10
  • 使用Python程序计算钢琴88个键的音高

    使用Python程序计算钢琴88个键的音高

    这篇文章介绍了使用Python程序计算钢琴88个键的音高,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • Python求两个字符串最长公共子序列代码实例

    Python求两个字符串最长公共子序列代码实例

    这篇文章主要介绍了Python求两个字符串最长公共子序列代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Python请求库发送HTTP POST请求的示例代码

    Python请求库发送HTTP POST请求的示例代码

    这段代码使用了Python的requests库来发送HTTP POST请求,向本地服务器的API发送数据,并处理响应,一步步解释这个代码
    2024-08-08
  • python函数指定默认值的实例讲解

    python函数指定默认值的实例讲解

    在本篇内容里小编给大家整理了一篇关于python函数指定默认值的实例讲解内容,有需要的朋友们可以跟着学习参考下。
    2021-03-03
  • python基于Selenium的web自动化框架

    python基于Selenium的web自动化框架

    这篇文章主要介绍了python基于Selenium的web自动化框架,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • 对python pandas读取剪贴板内容的方法详解

    对python pandas读取剪贴板内容的方法详解

    今天小编就为大家分享一篇对python pandas读取剪贴板内容的方法详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • Python开发之os与os.path的使用小结

    Python开发之os与os.path的使用小结

    这篇文章主要介绍了Python开发之os与os.path的使用小结,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2024-05-05

最新评论