当前位置: 代码网 > it编程>前端脚本>Python > Python使用BeautifulSoup抓取和解析网页数据的入门教程

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

2026年05月13日 Python 我要评论
很多 python 初学者学完基础语法之后,都会很自然地遇到一个问题:我能不能把网页里的内容提取下来,变成自己能处理的数据?比如:抓取文章标题提取商品名称和价格收集招聘信息批量整理博客链接分析网页中的

很多 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抓取和解析网页数据的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com