Python 网络爬虫:完整指南 [2026]
Python 语言 网络爬虫 早已超越了从静态页面中提取 HTML 的简单脚本。现代网站高度依赖 JavaScript 渲染、激进的反机器人系统、指纹识别和速率限制,这意味着如今用 Python 成功完成网页抓取所需的远不止 requests 和 BeautifulSoup。
在本指南中,你将了解 2026 年 Python 网页抓取的实际工作方式、如何抓取静态和动态网站,以及如何针对不同目标选择合适的工具。如果你处理的是表格数据,请参阅我们的 Python 表格抓取教程 查看实际示例。
我们将涵盖从 requests、BeautifulSoup 和 lxml 到 Playwright、Scrapy 和 curl_cffi 的所有内容,同时还包括处理分页、轮换代理、浏览器指纹、Cloudflare 保护以及大规模抓取工作流程的实用技巧。
什么是网页爬取?
网络爬虫 是指从网站自动提取数据。你编写一个程序,访问某个 URL,下载页面的 HTML,定位包含所需数据的元素 — 价格、产品名称、新闻文章、联系方式 — 并将这些数据保存为 CSV、JSON 或数据库等结构化格式。
2026 年 Python 之所以成为网络爬虫的首选语言,原因有三:它的库开箱即用地覆盖了整个流程的每一个环节,代码可读性足够高,连非工程师也能维护,而且它拥有规模最大的社区专门为爬虫打造工具。根据大多数开发者调查,超过 70% 的网络爬虫都是用 Python 编写的。
无论你是用 Python 做小型研究项目的网页抓取,还是构建生产级的数据管道,它都提供了成熟的库来处理 HTTP 请求、HTML 解析、浏览器自动化、异步爬取和反爬虫应对。
Python 网页抓取的常见用例:
- 价格监控 在电商网站上追踪竞争对手的定价
- 潜在客户开发 — 收集企业名录、联系页面、招聘板
- 市场调研 ——汇总产品评论、社交舆情、新闻报道
- 学术研究 从公开来源构建数据集,用于 NLP 或 ML 训练
- 房地产数据 ——收集商品信息、价格趋势、房产详情
- SEO 监测 — 追踪排名、提取 SERP 特性、监控反向链接
- 旅游与酒店业 — 抓取机票价格、酒店空房和评价
网页抓取合法吗?
抓取公开可用的数据处于法律灰色地带,其合法性因司法管辖区、目标网站以及抓取方式的不同而有所差异。2022 年具有里程碑意义的判决 hiQ Labs 诉 LinkedIn 案 (美国第九巡回法院)确认,抓取公开可访问的数据通常不违反《计算机欺诈和滥用法》——但该判决并不意味着可以对一切行为一概放行。
抓取任何网站前的实用检查清单:
| 因素 | 需要检查的内容 | 忽视后的风险 |
| robots.txt | 检查 /robots.txt 中的 Disallow 指令 | 违反服务条款、民事索赔 |
| 服务条款 | 阅读服务条款,许多条款明确禁止自动化访问 | 违反协议、账号被封 |
| 个人数据(GDPR/CCPA) | 在没有法律依据的情况下,不要收集或存储姓名、电子邮件、标识符 | 监管罚款(2000 万欧元以上) |
| 速率限制 | 添加延迟——在某些司法管辖区,激进的抓取行为可能构成 DoS 攻击 | 刑事责任 |
| 需要登录才能访问的内容 | 绝不抓取你无权访问的登录后内容 | 违反 CFAA |
| 版权 | 提取受版权保护的创意作品(文本、图像)受到单独的法律保护 | DMCA 下架通知、法律诉讼 |
网页抓取的工作原理
在写下第一行 Python 代码之前,先理解底层究竟发生了什么,能让一切调试工作都变得更轻松。
- HTTP Request
你的抓取程序向某个 URL 发送 HTTP GET 请求。服务器收到请求后,会决定是返回 HTML 还是将你屏蔽。
- 服务器响应
服务器会返回页面的 HTML(静态网站),或者返回一个初始的 HTML 外壳,再由 JavaScript 填充内容(动态网站)。在选择工具之前,你需要先了解自己面对的是哪种类型。
- HTML 解析
解析器会读取 HTML 树,并根据元素的标签、class、ID 或 XPath 定位它们。你就是在这里提取你想要的具体数据。
- 数据清洗
原始 HTML 中包含空白字符、特殊字符和格式噪音。你需要将其清洗并规范化为干净、可用的值。
- 存储
保存为 CSV、JSON、数据库,或推送到 API。合适的格式取决于你接下来要如何使用这些数据。
静态页面 vs. 动态页面:这决定了一切
在编写任何爬虫之前,最重要的问题是:数据是在原始 HTML 源代码中,还是由 JavaScript 加载的?
右键点击页面 → View Page Source。如果你的数据在该源代码中可见,那它就是静态的。如果你看到的是一个大部分为空的外壳,其中包含 <div id="”app”"></div>,它是动态加载的,你需要使用像 Playwright 这样的浏览器自动化工具。
Python 库:选择合适的工具
Python 网络爬虫并没有唯一“最好”的库。合适的工具取决于目标页面的类型、项目的规模以及你对延迟的要求。以下是完整的概览:
| 库 | Role | 能处理 JS 吗? | 速度 | 最适合 |
| requests 库 | HTTP 抓取 | 🔴 否 | 🟢 快速 | 静态页面、API |
| BeautifulSoup4 | HTML 解析 | 🔴 否 | 🟡 中等 | 用简单的选择器解析 HTML |
| lxml | HTML/XML 解析 | 🔴 否 | 🟢 非常快 | 大型页面、XPath 高级用户 |
| Playwright | 浏览器自动化 | 🟢 是 | 🟡 较慢 | JS 密集型网站、表单交互 |
| Selenium | 浏览器自动化(旧方案) | 🟢 是 | 🔴 最慢 | 遗留项目、现有测试套件 |
| Scrapy | 完整的爬取框架 | 🧩 插件 | 🟢 非常快 | 1,000 多个页面、生产级流水线 |
| curl_cffi | TLS 指纹安全的 HTTP | 🔴 否 | 🟢 快速 | 受 Cloudflare 保护的网站 |
| HTTPX 库 | 异步 HTTP 客户端 | 🔴 否 | 🟢 快速 | 异步抓取、HTTP/2 支持 |
库选择决策树
数据是否存在于查看源代码(原始 HTML)中?
├── 是
│ ├── 小型项目(1–100 个页面)? → requests + BeautifulSoup
│ ├── 需要极致速度 / XPath? → requests + lxml
│ └── 大规模爬取(1,000+ 页面)? → Scrapy
└── 否(由 JavaScript 渲染)
├── DevTools → Network → XHR 中有 JSON API 吗?
│ └── 是 → requests(直接调用 API——最快!)
└── 没有真正的 API
├── 被 Cloudflare 拦截了? → curl_cffi 或 Playwright + stealth
└── 标准 JS 渲染? → Playwright(优于 Selenium)
第一个 Python 网页爬虫
设置与安装
编码前先检查
这一步能省去数小时的烦恼。在编写任何 Python 代码之前,先打开浏览器的 DevTools(F12),点击 元素 标签页,将鼠标悬停在你想提取的数据上。记下 HTML 标签、类名以及任何父级结构。你将在 Python 中使用的选择器会直接对应到你在这里看到的内容。
完整可运行的抓取器
我们将抓取 books.toscrape.com,这是一个专为练习爬取而设的沙盒网站,因此完全合法,也不会封锁你。
🚀 提示: 使用 lxml 作为 BeautifulSoup 解析器(BeautifulSoup(html, “lxml”))而不是 html.parser。它在处理大型页面时明显更快,并且能更从容地应对格式不规范的 HTML。
CSS 选择器和 XPath:定位你的数据
选对选择器,决定了你的抓取器是能稳定运行数月,还是每次网站更新 CSS 就崩溃。下面是实用指南。
CSS 选择器(推荐用于大多数场景)
XPath(最适合复杂遍历)
🚀 提示: 在 Chrome DevTools 中,右键点击任意元素 → Copy → Copy selector(或 Copy XPath)。这能给你一个起点,不过自动生成的选择器往往很脆弱。可以通过定位稳定的属性来简化它们,例如 data-* 属性、ID 或语义化的类名,而不是基于位置的选择器。
使用 Playwright 抓取由 JavaScript 渲染的页面
相当一部分现代网站(电商、SaaS、社交平台)会在初始 HTML 加载完成后通过 JavaScript 渲染内容。如果你在查看源代码中找不到所需数据,就需要一个能运行真实浏览器的工具。
Playwright 是现代之选 在 2026 年胜过 Selenium:它更快,拥有更简洁的 API,原生支持异步,并且内置的等待机制更好。Selenium 对于遗留项目仍然可用,但对于新工作,请从 Playwright 开始。
设置
基础版 Playwright 爬虫
异步 Playwright(用于并发抓取多个页面)
🚀 提示:先查看 Network(网络)选项卡。 在切换到 Playwright 之前,先打开 DevTools → Network → Fetch/XHR 并重新加载页面。许多看似由 JS 渲染的网站,实际上会暴露一个干净的 JSON API 接口。直接用 requests 调用该接口,比启动一个浏览器要快 10–50 倍,而且稳定得多。
处理分页
真实的抓取目标几乎从来不会只在单个页面上。以下是两种常见的模式以及如何处理它们。
模式 1:基于 URL 的分页
许多网站使用可预测的 URL 模式: /page/2, ?page=3, &start=40。这些是最容易处理的。
模式 2:“下一页”按钮爬取
当 URL 无法预测时,可以直接从 HTML 中跟踪指向下一页的链接。
存储抓取的数据
合适的存储格式完全取决于你后续要如何处理这些数据。下面是每个选项的决策指南和实现方法。
| 格式 | 最适合 | 最大规模 | 可查询? |
| CSV | 一次性导出、Excel/pandas 消费 | 约 10 万行 | 否 |
| JSON | API、嵌套/不规则的数据结构 | 约 10 万行 | 否 |
| SQLite | 去重、本地查询、中等规模 | 约 1000 万行 | 是 |
| PostgreSQL | 生产流水线、多用户、大规模场景 | 无限 | 是 |
| pandas DataFrame | 即时数据分析/可视化 | 内存上限 | 是 |
抓取工具为何被封锁以及如何解决
这是大多数 Python 网页抓取教程完全跳过的部分,也是大多数爬虫在生产环境中失败的原因。反爬系统是分层运作的,理解每一层是绕过它的第一步。
检测栈(按触发时机排序)
| Layer | 它检测什么 | 修复 | |
| 1 | TLS 指纹识别 | 你的 TLS ClientHello 的 JA3/JA4 哈希值——在读取请求头之前就已触发 | 使用 curl_cffi 模拟真实浏览器的 TLS 栈 |
| 2 | HTTP 请求头 | 裸 requests 请求头与真实浏览器毫无相似之处 | 设置完整、真实的请求头集合,包括 Sec-Fetch-* |
| 3 | IP 信誉 | 数据中心 IP 会被标记;来自同一个 IP 的请求过多 = 封锁 | 每次请求轮换住宅代理 |
| 4 | 请求时序 | 机器般精准的时间间隔是一种机器人信号 | 随机延迟(1–4秒),间隔加入抖动 |
| 5 | 浏览器指纹 | 无头浏览器泄露:navigator.webdriver、缺失的插件、canvas 哈希 | 搭配 playwright-stealth 的 Playwright |
| 6 | 行为分析 | 没有鼠标移动、滚动或交互模式 | 配合随机化鼠标/滚动模拟的 Playwright |
第 1 层:使用 curl_cffi 绕过 TLS 指纹
这是 2026 年最常被忽视的修复方法。Cloudflare、Akamai 和 DataDome 会检测 TLS ClientHello 消息,甚至在你的 HTTP 头到达之前就出现了。Python 的标准 requests 库 库会生成一个极易被识别为非浏览器的指纹。解决办法是 curl_cffi:
第 2 层:设置真实的 HTTP 请求头
第 5–6 层:隐身 Playwright
在 Python 中使用住宅代理
IP 屏蔽是 Python 抓取程序在生产环境中失败的最常见原因。一旦某个网站通过速率限制、数据中心 ASN 检测或指纹识别锁定了你的 IP,来自该地址的每一个请求都会被屏蔽。唯一可靠的解决方案是 使用住宅 IP 进行代理轮换.
为什么偏偏是住宅代理?
| 代理类型 | 检测风险 | 速度 | 最适合 |
| 数据中心 | 🔴 高——ASN 很容易被标记 | 🟢 快速 | 仅适用于低防护网站 |
| 住宅代理 | 🟢 低 — 真实 ISP 的 IP | 🟡 中等 | 大多数电商、新闻和数据类网站 |
| ISP(静态住宅) | 🟢 低 — 住宅信任度 + 速度 | 🟢 快速 | 基于会话的抓取、登录流程 |
| 移动网络(4G/5G) | 🟢 极低 — 运营商 IP 受信任 | 🟡 视情况而定 | 防护严密的网站、社交平台 |
住宅代理 会将你的请求通过 ISP 分配的真实家庭 IP 地址进行路由,也就是人们在家中上网时使用的那种 IP。在目标网站看来,这些流量与真实用户活动别无二致。这正是它们成为严肃 Python 网页抓取首选方案的原因。
使用 NodeMaven 代理安全地开始抓取
NodeMaven 面向 Python 的代理 3000 万以上经过预筛选的住宅 IP,为抓取程序带来超过 98% 的成功率。
每个 IP 都会经过一道 质量过滤 ——池中没有被封、被标记或被回收的地址。提供轮换和静态两种选项、SOCKS5 + HTTPS,以及覆盖多地的 ZIP 级地理定位,遍及 190+ 个地区。
用 requests 实现基础代理集成
每次请求轮换代理
为实现最强的反检测效果,请在每一次请求时都轮换代理,让每个请求看起来都来自不同的用户:
基于会话的代理(用于登录流程)
在登录后进行抓取时,或任何需要在多个请求中使用同一 IP 的工作流,请使用粘性会话代理:
用于本地化数据的地理定向代理
最强大的用例之一是 住宅代理 在 Python 抓取中,访问特定地区的内容是一大挑战:本地化定价、搜索结果、产品可用性或受地理封锁的页面。NodeMaven 支持 ZIP 级定位,这是目前可用的最精细的地理定位:
搭配 Playwright 使用代理
生产环境重试逻辑
NodeMaven 的 IP 质量过滤器使其区别于普通代理服务商。IP 在进入资源池之前,会先与欺诈数据库比对并进行评分。只有记录干净、欺诈评分低于 70% 的 IP 才会被提供使用 — 这意味着您会遇到更少的 403 错误、更少的 CAPTCHA,并且无需频繁轮换即可维持更长的抓取会话。 了解质量过滤机制
使用 Scrapy 进行扩展
对于需要抓取成千上万甚至数百万个页面,或者需要按计划运行并配备重试逻辑、速率限制和结构化数据管道的项目而言,Scrapy 是正确的选择。它开箱即用地处理并发、中间件、item 管道以及部署。
快速设置
带有代理中间件的生产级爬虫
调试与错误处理
| 错误 / 症状 | 可能的原因 | 修复 |
| 403 Forbidden | 缺少请求头或 IP 被封锁 | 添加完整请求头;切换代理 |
| 429 请求过多 | 触发了速率限制 | 增加/加大延迟;轮换代理 |
| AttributeError: ‘NoneType’ | select_one() 未返回任何内容 | 打印原始 HTML;在 DevTools 中验证选择器 |
| select() 返回空列表 | JS 渲染的内容 | 改用 Playwright;检查 XHR 中的 API |
| 返回了 CAPTCHA 页面 | 触发了机器人检测 | 住宅代理 + 隐身请求头 |
| ConnectionError / ProxyError | 代理失败或超时 | 重试逻辑;用 httpbin.org 测试代理 |
| 数据看起来有误或被截断 | 选择器错误或编码错误 | 打印 soup.prettify();检查 response.encoding |
| SSLError | 证书问题 | verify=False(仅限开发环境)或更新证书 |
| Playwright 超时 | 选择器始终未出现(JS 未执行成功) | 增加超时时间;添加 networkidle 等待 |
黄金调试法则
当选择器返回为空时,首先要做的是打印你实际收到的内容,而不是你期望的内容:
完整速查表



