当前位置:

首页 > 编程开发 > Python使用BeautifulSoup抓取和解析网页数据的入门教程

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

很多 Python 初学者学完基础语法之后,都会很自然地遇到一个问题: 怎么能把网页里那些看起来零零散散的内容,给“薅”下来,变成自己能处理的数据呢? 比如: 抓取文章标题 提取商品名称和价格 收集招聘信息 批量整理博客链接 分析网页中的表格和列表 这时候,BeautifulSoup 往往就是最适合

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

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

怎么能把网页里那些看起来零零散散的内容,给“薅”下来,变成自己能处理的数据呢?

比如:

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

这时候,BeautifulSoup 往往就是最适合入门的那把“瑞士军刀”。它不像那些大型爬虫框架,一上来就甩给你一堆工程化的概念,也不像正则表达式那样,写出来像天书,自己都看不懂。它做的事情很纯粹,也很优雅:

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

如果你现在正在学习 Python,又对网页数据抓取跃跃欲试,这篇文章就是为你量身定做的。我们会从 0 开始,把以下这些问题彻底讲清楚:

  • BeautifulSoup 到底是什么?
  • 它和 requests 是怎么分工的?
  • 如何把网页的 HTML 抓下来?
  • 如何用 find()find_all()select() 这些核心方法精准锁定数据?
  • 如何写一个完整的小型抓取脚本?
  • 实际开发中,有哪些坑是必须提前绕开的?

1. BeautifulSoup 是什么

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

你可以把它想象成一个“网页内容整理员”。网页源码本质上就是一大段字符串,里面各种标签混杂在一起,比如:

Python 入门

查看详情

如果你直接对着这段字符串用切片、写正则去抠,那代码会脆弱得跟纸糊的一样,页面结构稍微一改,你的代码就废了。

而 BeautifulSoup 的厉害之处在于,它先把这段混乱的 HTML 解析成一个结构化的对象。之后,你就像查一棵树一样,可以很优雅地找到:

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

这也是它名字里 Soup 的由来 —— 再乱的“网页汤”,它都能帮你整理得清清爽爽,让你轻松“舀”出想要的内容。

2. BeautifulSoup 和 requests 是什么关系

这几乎是每个新手都会混淆的问题。其实它们的职责非常清晰,可以说是“最佳拍档”:

  • requests:负责“跑腿”。去向网站发请求,把网页的内容整个下载回来。
  • BeautifulSoup:负责“拆包”。把你拿回来的 HTML 内容,解析成好用的结构,然后从中提取数据。

所以它们经常成对出现,标准流程如下:

  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 练手,把原理搞明白。下面这段代码,可以说是 BeautifulSoup 的“Hello World”:

from bs4 import BeautifulSoup


html = """

  
    

Python 学习笔记

这是一个 BeautifulSoup 示例页面

第一篇文章 第二篇文章 """ 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,并告诉它用 Python 自带的 html.parser 来“消化”它。之后,你就可以通过 soup.h1find()select() 这些方式去拿数据了。

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

BeautifulSoup 的 API 不算少,但对新手来说,真正核心、用得最多的,就下面这几个。

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

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

如果页面里有多个 h1 标签,它只会返回第一个找到的。你也可以通过属性来精确匹配:

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

注意,这里用的是 class_,后面有个下划线,因为 class 是 Python 的保留关键字,不能直接拿来用。

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

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

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

  • 所有文章链接
  • 所有商品卡片
  • 所有招聘信息条目

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

如果你有前端基础,你会爱上这个方法的。它允许你用写 CSS 的方式来找元素。

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

常见写法示例:

  • div:选择所有 div 标签
  • .card:选择 class 为 card 的所有元素
  • #main:选择 id 为 main 的元素
  • .article-list a:选择 article-list 这个区域下的所有 a 标签

在实际项目中,select()select_one() 用起来往往比 find() 更顺手,也更灵活。

5.4 get_text() 和 get()

提取文本:

text = title.get_text(strip=True)

提取属性:

href = link.get("href")

这两个方法的区别必须搞清楚:

  • get_text():拿的是标签“里面”的文字内容。
  • get("href"):拿的是标签“上面”的属性值,比如链接地址。

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

下面这个示例,会更接近真实项目的样子。我把完整的代码整理了一下,方便你本地直接跑起来验证。假设我们有这样一个 HTML 结构:

beautifulsoup_web_scraping_demo.py

代码如下:

from __future__ import annotations

from bs4 import BeautifulSoup
import requests


SAMPLE_HTML = """



    
    BeautifulSoup Demo


    
""" 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. 新手最常见的一个误区:一上来就抓整页

很多新手上来就喜欢对着整个页面用 soup.find_all("a"),以为这样就能拿到所有文章的链接。

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

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

最后拿到的数据会很乱,你需要浪费大量时间在“清洗”上。

更好的做法是,先从“结构”入手:

  1. 先找到存放数据的列表区域,比如一个 div.article-list
  2. 再在这个区域里,遍历每一个 div.article-card
  3. 最后,在每一张 card 里,提取标题、链接、作者这些具体信息。

所以,尽量从 soup.select(".article-card") 这种“按块定位”的方式入手,而不是在整个页面里“大海捞针”。

9. BeautifulSoup 常见解析器怎么选

创建 BeautifulSoup 对象时,第二个参数就是解析器。

BeautifulSoup(html, "html.parser")

常见的有三个选择:

  • html.parser:Python 自带,无需额外安装,最省事。
  • lxml:速度更快、容错性也强一些,是很多项目的首选,但需要安装。
  • html5lib:容错性最强,能处理一些极其不规范的页面,但速度最慢,也最重。

给新手的建议非常明确:

  • 学习阶段,用 html.parser 就足够了,不要浪费时间在“选哪个解析器”上。
  • 等后面做正式项目了,再考虑换成 lxml 来提升性能。

先跑通流程,远比一开始就纠结“哪个性能更好”重要得多。

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

这是 BeautifulSoup 初学者最常遇到的一个坑,让人抓狂。你明明在浏览器里看到了内容,但用 requests.get() 拿回来的 HTML 里却没有。

绝大多数情况下,原因只有一个:

这个页面的关键数据是通过 Ja vaScript 动态加载的。

什么意思呢?就是浏览器打开页面后,它还会去执行 JS 代码,再向后台的接口请求数据,最后把内容“渲染”出来给你看。而 requests 拿到的,只是那个“空壳”页面最初的 HTML。

这时候,BeautifulSoup 本身没问题,问题在于你给它“吃”的输入源就是残缺的。

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

  • 最推荐的做法:打开浏览器的“开发者工具”(F12),找到那些加载数据的接口,直接去抓取接口返回的 JSON 数据,那才是纯净的结构化数据。
  • 次选方案:使用 Playwright、Selenium 这类“浏览器自动化”工具,它们能真正打开一个浏览器去渲染页面,然后你再把渲染后的 HTML 交给 BeautifulSoup 处理。

记住一个核心原则:

BeautifulSoup 擅长解析 HTML,但它绝不会替你执行任何前端 Ja vaScript 代码。

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

这部分内容,往往比语法本身更重要,很多坑都是在这里。

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

真正的抓取工作,不是看到标签就往上怼代码。正确的做法是先打开“开发者工具”,冷静地观察页面结构:

  • 每条数据的容器标签是什么?
  • 标题在哪个标签里?有什么独特的 class 或 id?
  • 链接藏在哪个属性里?
  • 时间、作者、价格这些信息,是否都在固定位置出现?

只有先分析清楚结构,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 的错误(比如404,500)暴露出来,否则你很可能在那对着一个报错页面拼命解析,还以为是自己的选择器写错了。

11.4 控制抓取频率

如果你需要抓取多页内容,务必在每次请求之间添加延时(比如 time.sleep(1))。用极高频率连续请求,不仅容易触发网站的反爬机制导致被封 IP,也会给目标网站服务器带来不必要的压力,这是一种很不专业的行为。

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

这一点需要时刻牢记。在动手之前,最好先看一眼目标网站的 robots.txt 和它的使用条款。技术上能做,不代表你就应该做。做个有职业道德的爬虫开发者。

12. BeautifulSoup 适合哪些场景

BeautifulSoup 的特性决定了它特别适合以下这些场景:

  • 目标网页的结构相对稳定,不会频繁改动。
  • 页面主要内容是静态的,直接写在 HTML 中,而非通过 JS 动态加载。
  • 抓取规模不大,可能几十个页面就搞定了。
  • 想快速写一个“一次性”的轻量脚本,快速验证想法。
  • 只是想先试试看,这个网页的数据到底能不能提出来。

比如下面这些任务,它都是完美人选:

  • 文章列表的抓取与整理。
  • 简单商品页面的信息提取。
  • 个人博客的导航页链接整理。
  • 网页中表格数据的提取。
  • 页面内所有链接的分析归类。

你的目标只是先把网页数据拿下来,为后续的分析和处理做铺垫,那么 BeautifulSoup 是一个非常好的起点。

13. BeautifulSoup 和 Scrapy 该怎么选

这几乎是每个走到这一步的人都会问的问题。它们不是竞争关系,而是适用于不同阶段。

  • BeautifulSoup 更像一个“折纸工具”,专注于“解析”这个单一任务。它轻巧、灵活。
  • Scrapy 则像一个“自动化车间”,是一个完整的爬虫框架。它包含了调度、下载、解析、存储等一整套流程。

简单来说:

  • 如果你的需求是抓一两个页面,或者几十个页面,快速写个脚本验证一下,重点放在解析本身,那就选 requests + BeautifulSoup,它更轻、更直接,学习成本也低。
  • 如果你的需求是爬成千上万个页面,需要处理自动跟进链接、去重、重试、分布式抓取、数据管道导出等复杂问题,那就该考虑 Scrapy 了。

所以,别把 BeautifulSoup 看作是“低配版 Scrapy”。它在自己擅长的领域里(快速开发、入门学习、轻量任务)就是最佳选择。

14. 给初学者的学习建议

如果你想真正掌握 BeautifulSoup,而不是仅仅停留在“会几个 API”的阶段,建议你遵循这个学习路径:

  1. 纸上谈兵:先用本地的 HTML 字符串反复练习 find()find_all()select() 这几个核心方法,确保概念清晰。
  2. 首战告捷:接着,尝试用 requests.get() 随便抓一个结构简单的静态网页下来。
  3. 真刀真枪:自己找一个结构简单的页面(比如一些纯粹的博客列表页),试着用 BeautifulSoup 去提取里面的文章标题和链接。
  4. 数据入库:把提取到的结果,整理成字典或列表,再尝试输出成 JSON 文件或者 CSV 文件。
  5. 触类旁通:最后,尝试从 CSV 里读取数据,写入到 Excel 或者简单的数据库中。

你会发现,真正的核心能力不在于背了多少 API,而在于:

看到一个网页,能快速判断它属于哪种结构,从哪里切入提取数据最省事。

15. 总结

BeautifulSoup 是 Python 生态里非常经典、也非常适合新手入门的网页解析库。它最大的价值不在于语法多高级,而在于它把“从网页里提取信息”这件事变得直观了太多。

最后,再帮大家回顾一下这套组合最核心的分工:

  • requests:负责“下载”网页。
  • BeautifulSoup:负责“拆解”网页。
  • 你的 Python 代码:负责“整理”数据,并进行后续的分析和处理。

如果你正在学习 Python,又希望尽快做出一些能解决实际问题的“小玩具”来提升成就感,那么 BeautifulSoup 绝对值得你亲手敲一遍。先从本地 HTML 开始,跑通选择器,再去挑战真实的网页,你的进步会快很多。

本文内容来源于互联网,如有侵权请联系删除。
作者最新文章
编程开发 Python
相关文章 更多
C++动态数组初始化怎么写?常用语句与代码示例
C++动态数组初始化怎么写?常用语句与代码示例

深入解析C++中动态数组的初始化机制,涵盖new操作符的不同用法、基本类型与类对象的初始化差异,以及为何在现代C++开发中应优先使用std::vector。

Python安装后怎么打开:使用IDLE或命令行启动解释器
Python安装后怎么打开:使用IDLE或命令行启动解释器

刚在Windows安装好Python却不知道如何启动?本文详细演示如何通过开始菜单找到并打开IDLE集成开发环境,以及如何在PowerShell或命令提示符中使用python和py命令启动交互式解释器、运行.py脚本文件。包含退出解释器的方法及常见启动问题排查,帮助初学者快速验证安装成功并开始编写代码。

Windows系统Python安装教程:下载、勾选PATH及环境变量配置
Windows系统Python安装教程:下载、勾选PATH及环境变量配置

针对Windows初学者的Python安装实战指南。详细讲解如何从Python官网下载匹配架构的安装包,重点演示安装首屏勾选“Add python.exe to PATH”的关键操作,并提供使用python --version和py命令验证环境变量的具体步骤,帮助新手快速搭建开发环境并排查路径问题。

麒麟OS如何查看Python进程的运行状态
麒麟OS如何查看Python进程的运行状态

要想确认麒麟OS中Python程序的运行状态以及资源占用情况,我们可以这样做:用ps -ef | grep python来筛选进程;通过top命令,按P键排序查看实时负载;使用pgrep -f "script.py"精准获取PID;借助lsof -p PID验证文件打开状态。另外,还可以结合syst

Python在Debian上如何配置SSL证书
Python在Debian上如何配置SSL证书

在Debian系统上配置SSL证书通常涉及以下几个步骤:安装Web服务器:首先,你需要一个Web服务器,比如Apache或Nginx。这里以Apache为例。sudo apt updatesudo apt install apache2获取SSL证书:你可以从Let’s Encrypt免费获取SSL

统信UOS怎么安装Python开发环境
统信UOS怎么安装Python开发环境

要想让Python项目在统信UOS上正常运行,得先安装python3、python3-pip、python3-venv、python3-dev以及build-essential等组件。具体操作就是执行sudo apt install命令来一步到位完成安装,同时别忘了配置清华镜像源来给pip加速哦。在

纯Python方案实现中英文全文搜索
纯Python方案实现中英文全文搜索

在互联网上的各类网站中,无论大小,基本上都会有一个搜索框,用来给用户对内容进行搜索,小到站点搜索,大到搜索引擎搜索。从简单的来说,搜索功能确实很简单,一个简单的select语句就可以实现数据的搜索。而从复杂的来看,无论是搜索的精度还是搜索的效率,都是有很深的研究范围的。对于简单的搜索功能来说,一个s

Mac如何取消通过Python脚本运行的关机程序
Mac如何取消通过Python脚本运行的关机程序

立即在终端输入sudo shutdown -c取消倒计时关机,成功后显示“Shutdown cancelled”;若存在pmset重复任务,需再执行sudo pmset repeat cancel清除。Mac因Python脚本执行了os.system("sudo shutdown -h +10")或

Pythonasyncio异步并发与多固定出口IP调度实战
Pythonasyncio异步并发与多固定出口IP调度实战

之前写过一篇同步场景下用 Python 管理多个固定出口 IP 的实践(ExitPool + requests/httpx),覆盖了健康检查、故障转移和连接池复用。但在实际业务中,越来越多的场景用 asyncio 做高并发采集或批量接口调用——异步事件循环下多出口的管理方式和同步场景完全不同:单线程

Python在静态出口IP产品中的实战:从地址漂移巡检到多IP故障切换
Python在静态出口IP产品中的实战:从地址漂移巡检到多IP故障切换

写在前面:为什么静态出口 IP 不是"买了就行"不少团队在引入静态出口 IP 产品时,第一反应往往是:“地址配上去,这事就算完了。”可真到了真实业务里,静态出口 IP 真正能体现价值的地方,往往不在分配这一步,而在分配之后怎么管:地址有没有漂移,质量是否达标,某一条线路突然不可用时怎么切换,连接层又

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

macOS软件
macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

Mac软件 更多
灵活计算器
灵活计算器
macOS/iOS/Android

灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

赤友清理大师
赤友清理大师
macOS

赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

WINDOWS 更多
Windows 10
Windows 10
Windows

Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

密码键盘
密码键盘
Windows/macOS/iOS/Android

密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。