
提到 Python 网络爬虫很多人第一反应是“用 requests 请求网页再用正则把数据抠出来”好像两行代码就能搞定。但真正动手做过的人都知道现实远没有这么简单明明在浏览器里能看到数据用 requests 请求却拿到 403刚才还能正常访问的页面多请求几次就直接封了 IP对着 Fiddler 抓包面板看了半天也不知道哪个请求才是数据接口。这些问题的根源在于爬虫从来不是“发请求 解析”这么简单而是一条完整的链路请求构造、抓包分析、数据解析、反爬识别、代理切换、封禁避坑。任何一环没打通都会让整个项目卡住。这篇文章我会把这条链路一次性讲清楚用可运行的代码和配置带你把地基打牢。不是零散地讲库函数而是从真实开发角度梳理爬虫工程师的工作方式。如果你正准备入门爬虫或者已经写过一些脚本但遇到反爬就束手无策这篇文章值得收藏。1. 这篇文章真正要解决的问题先说说爬虫学习中最常见的几个误区。第一个误区是“只学 requests不学抓包”。很多教程会告诉你requests.get(url)就能拿到 HTML于是你背下了这个用法却忽视了真正重要的能力怎么从浏览器或 App 的请求里找到你需要的那个接口。等到要爬的数据不是静态 HTML而是异步加载出来的 JSON 时你就不知道怎么下手了。第二个误区是“把反爬想得太难或者想得太简单”。有些人一看到 403 就放弃认为目标网站不可能爬有些人则直接上高并发结果 IP 被拉黑连正常浏览都受影响。实际上大多数反爬机制都是“成本博弈”不是不可逾越的墙。关键是你得先判断对方到底在检测什么再用对应的方式应对。第三个误区是“一上来就追求高并发”。爬虫工程的本质不是越快越好而是越稳越好。一个目标网站的反爬策略、数据更新频率、服务器承受能力都决定了你要用多慢的速度去爬而不是用多快的速度去抓。这篇文章的核心判断是爬虫真正考验的不是“你会不会发请求”而是你会不会观察、分析和模拟真实用户行为。你需要把请求、抓包、解析、反爬、代理、防封当成一个整体去学习才能从“能跑脚本”进阶到“能做项目”。如果你的目标是学习技术、分析公开数据、做个人项目这篇文章的路线足够你起步。我会尽量用通用示例让你不依赖某个具体网站也能跑通代码。2. 网络爬虫完整链路先看懂再动手在写代码之前你要先理解一整条链路长什么样。爬虫项目一般可以拆成五个环节。2.1 请求环节模拟客户端发出 HTTP 请求请求环节的核心是 requests 库。它会帮你构造 HTTP 请求拿到服务器的响应。看起来简单但真正做项目时会涉及请求头Headers模拟浏览器标识、Referer、Cookie。请求体BodyPOST 提交的表单或 JSON。会话保持Session维持登录状态。超时与重试避免网络抖动拖垮整个任务。2.2 抓包环节找到真实的数据接口浏览器地址栏里看到的 URL不等于浏览器真正请求的 URL。很多页面的数据是异步加载的初次拿到的 HTML 只是一个壳真正的数据藏在某个 JSON 接口里。抓包工具的作用就是记录浏览器或 App 发出的每一个请求帮你筛选出真正需要的那一个。常用工具有浏览器开发者工具F12、Fiddler、Charles 等。2.3 解析环节从响应中提取目标数据拿到响应之后你需要从 HTML、JSON、XML 等格式中提取目标数据。HTML 页面可以用 BeautifulSoup、XPath 或正则表达式解析JSON 接口直接用json模块解析。2.4 反爬识别与应对服务器可能会通过 User-Agent、Referer、Cookie、请求频率、JavaScript 渲染、验证码等方式区分“真人用户”和“爬虫脚本”。你需要先识别对方用了什么策略再逐步模拟真实用户的行为。2.5 代理与防封当目标网站对同一 IP 的请求数量有限制时你需要通过代理 IP 轮换来分散请求压力。同时要控制频率、加随机延迟、配置重试退避避免触发风控。防封的核心不是“绕”而是“别让服务器觉得你是机器”。下面用一个表格概括这条链路和对应的技能点链路环节核心工具/库主要解决的问题请求发送requests、httpx构造请求、保持会话、模拟浏览器抓包分析F12、Fiddler、Charles定位数据接口、查看参数规律数据解析re、BeautifulSoup、lxml、json从响应中提取目标字段反爬应对请求头、Cookie、JS渲染处理通过服务器的基础风控代理防封代理池、请求频率控制分散 IP 压力降低封禁风险所有付费爬虫课程的核心内容其实就是这五块。本文后面会按这个链路逐层展开。3. 环境准备与前置条件开始写代码之前先把基础环境准备好。以下内容以 Windows 为主macOS 和 Linux 操作思路一致命令略有差异。3.1 安装 Python建议使用 Python 3.8 及以上版本。绝大多数爬虫库都已经兼容新版本老版本会遇到依赖安装问题。到 Python 官网下载安装包时务必勾选“Add Python to PATH”否则命令行里找不到python。安装完成后打开终端验证python --version如果输出Python 3.x.x就说明安装成功。3.2 创建虚拟环境不同项目的依赖版本可能互相冲突建议每个爬虫项目都创建一个独立的虚拟环境。mkdir python-spider-tutorial cd python-spider-tutorial python -m venv venvWindows 激活虚拟环境venv\Scripts\activatemacOS / Linux 激活方式source venv/bin/activate激活后命令行提示符会多出一个(venv)前缀。3.3 安装核心依赖本文要用到的库包括 requests、BeautifulSoup4、lxml。安装命令如下pip install requests beautifulsoup4 lxml关于版本建议安装最新稳定版即可。开发过程中如果遇到 SSL 证书报错可以检查 Python 版本和系统证书配置不要盲目关闭证书校验。3.4 开发工具写爬虫脚本不一定要用大型 IDEVS Code 或者 PyCharm 都可以。VS Code 装上 Python 插件后能直接调试脚本、查看变量日常开发完全够用。对于抓包分析先用好浏览器 F12再按需安装 Fiddler 或 Charles。4. 第一层requests 请求与响应处理requests 是 Python 爬虫最基础的库。你不需要背所有参数但下面这几个能力一定要掌握。4.1 一个最小请求示例# quick_request.py import requests url https://httpbin.org/get headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 } resp requests.get(url, headersheaders, timeout10) print(状态码:, resp.status_code) print(响应内容:, resp.text)这段代码做了三件事指定了 User-Agent告诉服务器“我是浏览器”。设置了 10 秒超时避免请求一直挂起。输出状态码和响应文本。运行后httpbin.org会返回请求信息其中包括你发过去的所有请求头。如果你发现某个网站返回 403第一步就是检查 User-Agent 是否像真实浏览器。4.2 Session 与异常处理如果你在同一个网站上连续请求多个页面且网站依赖 Cookie 维持状态建议使用requests.Session()。Session 会自动保存 Cookie并复用底层连接。# session_demo.py import requests from requests.adapters import HTTPAdapter session requests.Session() session.headers.update({ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 }) # 设置重试策略最多重试 3 次遇到连接错误、超时会自动重试 adapter HTTPAdapter(max_retries3) session.mount(http://, adapter) session.mount(https://, adapter) try: resp session.get(https://httpbin.org/cookies/set?namespider, timeout5) resp.raise_for_status() print(请求成功:, resp.status_code) except requests.Timeout: print(请求超时请检查网络或目标站点状态) except requests.RequestException as e: print(请求失败:, e)这里的raise_for_status()会在状态码为 4xx/5xx 时抛出异常避免你拿到一个错误页面还在继续解析。加 HTTPAdapter 重试则能提升稳定性但重试次数别太多否则等于帮对方加重风控。4.3 让抓包工具看到你的请求排查问题时我们经常需要确认脚本发出的请求和浏览器里的请求是否一致。这时可以让 requests 走本地代理用 Fiddler 或 Charles 查看。# proxy_debug.py import requests proxies { http: http://127.0.0.1:8888, https: http://127.0.0.1:8888 } resp requests.get(https://httpbin.org/get, proxiesproxies, timeout10) print(resp.status_code)Fiddler 默认监听 8888 端口Charles 默认监听 8888 端口或 8888 根据版本有所不同。配置好之后你可以在抓包工具中看到脚本发出的完整请求头。这个技巧在“requests 请求成功但浏览器请求也成功为什么数据还是不一致”的场景下非常有用。5. 第二层用抓包工具定位真实接口会写 requests 只是第一步。很多新手卡住不是不会发请求而是不知道该请求哪个 URL。5.1 F12 与 Fiddler / Charles 的区别浏览器开发者工具是最快的抓包方式。打开网页按 F12切到 Network 面板刷新页面就能看到所有网络请求。它的优点是零配置缺点是只能看浏览器的请求看不到手机 App 的请求。Fiddler 和 Charles 是独立抓包工具可以捕获桌面应用、手机 App 的 HTTP/HTTPS 请求。它们的原理是在你的电脑上开一个本地代理所有经过代理的流量都会被记录下来。工具适用场景优点注意点浏览器 F12网页爬虫零配置使用简单只能看浏览器环境FiddlerWindows 桌面端、网页功能全面可断点修改请求需要安装并信任根证书CharlesmacOS、手机 App界面友好适合 App 调试需要与手机配置代理5.2 从抓包结果中筛选数据接口打开任意一个包含数据列表的网站你会发现 Network 面板里有几十个请求。哪些才是真正的数据接口一个有效方法是按 XHRXMLHttpRequest或 Fetch 过滤。页面上异步加载的数据通常都是 XHR 或 Fetch 请求。然后逐个点击请求在 Preview 或 Response 标签页里搜索你要的数据。比如列表页里出现了“标题”“价格”等关键字段基本可以确定这就是数据接口。找到接口后重点关注三部分请求 URL。请求方法GET 还是 POST。请求头里的关键字段比如 Cookie、Referer、Token。然后在 requests 中模拟这个请求通常就能拿到同样的数据。5.3 手机 App 抓包的特殊性抓手机 App 的包比网页复杂一些。基本流程是电脑上打开 Fiddler 或 Charles开启代理并记录端口。手机连接同一局域网手动设置代理为“电脑 IP 端口”。手机浏览器访问抓包工具的证书下载地址安装并信任根证书。打开目标 App操作界面观察抓包工具中的请求。这里最容易踩的坑是“App 抓不到包”。常见原因包括手机没有正确安装或信任根证书。App 开启了证书固定Certificate Pinning拒绝非系统证书。App 不走系统代理需要配合其他工具处理。遇到这些情况不要急着怀疑工具先确认证书有没有装对、代理有没有生效。6. 第三层数据解析的三种姿势拿到响应之后就要把目标数据提取出来。解析方式取决于响应格式HTML 用 BeautifulSoup 或 XPathJSON 用 json 模块纯文本可以上正则。6.1 正则表达式适合简单场景正则最灵活但可读性最差。当数据结构非常简单、或者字段藏在 HTML 属性中时可以直接用正则提取。import re html a href/detail/101 titlePython爬虫教程Python爬虫/a match re.search(rhref(/detail/\d) title([^]), html) print(match.group(1)) # /detail/101 print(match.group(2)) # Python爬虫教程正则的优点是无需额外依赖缺点是一旦页面结构调整正则很容易失效。能用解析库的场景不建议优先用正则。6.2 BeautifulSoup适合 HTML 页面BeautifulSoup 是解析 HTML 最友好的库之一它可以按标签名、class、id 等属性查找元素对网页结构不熟悉的人也能快速上手。from bs4 import BeautifulSoup html html body div classnews-list div classitem h3a href/news/1新闻标题一/a/h3 span classtime2025-01-01/span /div div classitem h3a href/news/2新闻标题二/a/h3 span classtime2025-01-02/span /div /div /body /html soup BeautifulSoup(html, html.parser) items soup.select(.news-list .item) for item in items: title item.select_one(h3 a).get_text(stripTrue) link item.select_one(h3 a)[href] pub_time item.select_one(.time).get_text(stripTrue) print(title, link, pub_time)select方法支持 CSS 选择器定位速度很快。用get_text(stripTrue)可以去掉多余空白。6.3 XPath适合复杂结构如果页面结构嵌套层级很深XPath 的定位能力比 CSS 选择器更强。BeautifulSoup 本身不支持 XPath需要搭配 lxml 使用。from lxml import html page html.fromstring(html) titles page.xpath(//div[contains(class, news-list)]//h3/a/text()) links page.xpath(//div[contains(class, news-list)]//h3/a/href) print(titles) print(links)lxml 的性能很高适合大批量数据解析。不过 XPath 写起来有一定门槛建议先在浏览器 Console 里跑$x(...)验证表达式再写进代码。6.4 JSON 接口解析如果抓包后发现数据接口返回的是 JSON解析就简单了直接转成 Python 字典。import json import requests resp requests.get(https://httpbin.org/json, timeout10) data resp.json() # 直接解析 JSON print(data[slideshow][title])对于嵌套很深的 JSON我会先用json.dumps(data, ensure_asciiFalse, indent2)打印出来肉眼确认字段结构再写提取逻辑。7. 第四层常见反爬机制与应对策略反爬不是一门玄学。绝大多数反爬策略都在检测同一个问题这个请求像不像真人发出的下面这些是最常见的检测维度。7.1 请求头检测服务器会检查 User-Agent、Referer、Origin、Accept-Language 等字段。最简单也最容易被忽略的反爬就是 UA 检测。如果你的 requests 没有指定 UA默认值是一串python-requests/x.x.x很多网站会直接拒绝。应对方式是构造一份完整的浏览器请求头并保证与你的目标环境一致。不要只改 User-AgentReferer 和 Origin 也会被检查。headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36, Accept: text/html,application/xhtmlxml,application/xml;q0.9,image/webp,*/*;q0.8, Accept-Language: zh-CN,zh;q0.9,en;q0.8, Referer: https://example.com/, }7.2 请求频率限制如果同一个 IP 在短时间内请求次数过多服务器会返回 429 Too Many Requests或者直接在风控层面封禁 IP。应对方式主要是限速和随机延迟。但要注意限速不是简单地time.sleep(1)而是加随机抖动让请求间隔更接近人类行为。import random import time time.sleep(random.uniform(0.5, 1.5))7.3 JavaScript 动态渲染有些网站的数据不是通过接口返回的而是由 JavaScript 在页面加载后动态渲染。这时直接请求 HTML 只能拿到一个空壳。应对思路有两种深入分析 JavaScript找到它调用的接口直接请求接口。使用 Selenium、Playwright 等浏览器自动化工具渲染页面后再抓取。第一种方式更高效第二种方式更通用。优先推荐第一种因为渲染整个页面会消耗大量资源也更容易触发反爬。7.4 验证码与登录当网站遇到验证码或强制登录时爬虫的复杂度会大幅上升。方案通常有使用官方 API。保持 Cookie 登录状态。接入 OCR 或打码平台识别验证码。但这里要特别提醒验证码是网站主动设置的安全边界。处理验证码之前必须确认你有合法授权。不建议为了爬取数据去绕过验证码更不建议从公开渠道抓取用户隐私数据。7.5 合法合规边界写爬虫之前先看目标网站的 robots.txt再看用户协议和版权声明。尊重数据所属方的规则不仅是为了避免法律风险也是行业基本素养。可以这样理解爬虫技术本身是工具工具没有原罪但使用工具的人要有边界意识。公开数据、授权数据、个人学习实验数据和会员数据、隐私数据、付费内容法律性质完全不同。8. 第五层IP 代理池与防封避坑当请求频率需要提升、或者同一 IP 已经被限制时代理 IP 就成了必需品。但代理不是越多越好这里面的坑也很深。8.1 代理 IP 解决了什么问题服务器可以通过 IP 判断请求来源。如果同一个 IP 在短时间内请求了太多页面就会触发频率限制。代理 IP 的作用是让你的请求分散到不同 IP 上降低单 IP 的请求压力。8.2 代理 IP 的类型与质量判断类型特点适用场景数据中心代理速度快、成本低不需要高匿名的场景住宅代理伪装成真实用户成功率更高反爬严格的目标站移动代理来自手机网络最难被识别App 数据采集代理质量可以从三个维度判断可用率测试连接成功的比例。响应速度代理延迟是否影响请求。匿名度服务器能否识别出你的真实 IP。8.3 代理池管理思路单个代理 IP 很容易失效生产环境一般用“代理池”来管理多个代理。下面是一个最小可用的代理池思路定义一批代理逐个测试把可用代理放入队列请求时循环获取。import random import requests PROXY_POOL [ http://127.0.0.1:7890, http://127.0.0.1:7891, http://127.0.0.1:7892, ] def fetch_with_proxy(url, headersNone): 从代理池中随机选择一个代理发起请求。 生产环境下这段逻辑应当改成动态拉取、定时验证、剔除失效代理。 proxy random.choice(PROXY_POOL) proxies {http: proxy, https: proxy} resp requests.get(url, headersheaders, proxiesproxies, timeout5) return resp生产环境的代理池要做得更复杂定时检测代理可用性、按延迟排序、自动剔除失效代理、统计每个代理的失败率。你可以用 Redis 存放代理列表用定时任务维护代理状态。8.4 防封核心原则很多人以为防封靠代理池其实代理只是其中一个环节。真正的防封策略是一个组合拳控制请求频率加随机延迟。设置重试退避失败后不要立刻重试先等待。不要并发轰炸控制并发数。模拟真实用户行为包括浏览顺序、点击间隔。优先使用 GET 请求避免频繁 POST。设置合理的超时时间避免请求堆积。一个简单的退避重试逻辑是这样import time import requests def request_with_retry(url, headersNone, max_retries3, backoff_factor2): for attempt in range(max_retries): try: resp requests.get(url, headersheaders, timeout10) resp.raise_for_status() return resp except requests.RequestException as e: wait backoff_factor ** attempt print(f第 {attempt 1} 次请求失败{e}等待 {wait} 秒) time.sleep(wait) return None8.5 什么时候才需要代理池如果只是学习练习访问几个公开页面完全不需要代理池。代理会在以下场景才真正需要目标网站对单 IP 有明确频率限制。你运行的是定时任务需要长时间持续采集。反爬策略已经根据 IP 维度封禁了你的访问。不要一上来就追求大规模代理池先做好限速和请求头大多数反爬都能被低成本解决。9. 综合实战一个可运行的完整爬虫项目把前面的知识串起来写一个完整的爬虫程序。这里我用公开的测试接口模拟一个采集任务实际项目中你只需要把 URL 替换成你有权访问的目标地址。9.1 项目目标从某个列表接口获取数据解析后保存到 CSV 文件。代码包含请求头伪装、超时重试、数据解析、CSV 落盘。整体结构可以直接迁移到真实项目。9.2 目录结构spider_demo/ ├── venv/ ├── requirements.txt └── spider.py9.3 代码实现# spider.py import csv import json import random import time import requests HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36, Accept: application/json, text/javascript, */*; q0.01, Accept-Language: zh-CN,zh;q0.9,en;q0.8, Referer: https://httpbin.org/, } def fetch_json(url, max_retries3): 请求 JSON 接口带简单重试和随机延迟 for attempt in range(max_retries): try: resp requests.get(url, headersHEADERS, timeout10) resp.raise_for_status() return resp.json() except (requests.Timeout, requests.ConnectionError) as e: print(f请求失败第 {attempt 1} 次{e}) time.sleep(2 ** attempt) except requests.HTTPError as e: print(fHTTP 错误{e}) break return None def parse_data(data): 从 JSON 中提取需要的字段返回列表 rows [] # 这里的字段结构以 httpbin.org 测试接口为例 # 实际项目中按目标接口的字段结构调整 if isinstance(data, dict): for key, value in data.items(): rows.append({ key: key, value: str(value) }) return rows def save_to_csv(rows, filenameoutput.csv): 将列表数据写入 CSV 文件 if not rows: print(没有数据可写) return fieldnames rows[0].keys() with open(filename, w, newline, encodingutf-8-sig) as f: writer csv.DictWriter(f, fieldnamesfieldnames) writer.writeheader() writer.writerows(rows) print(f已保存 {len(rows)} 条数据到 {filename}) def main(): url https://httpbin.org/json data fetch_json(url) if data is None: print(获取数据失败) return rows parse_data(data) save_to_csv(rows) if __name__ __main__: main()代码逻辑说明fetch_json负责请求处理超时、连接错误、HTTP 错误并带退避重试。parse_data负责把 JSON 转换成统一结构方便写 CSV。save_to_csv使用utf-8-sig编码避免 Excel 打开 CSV 时中文乱码。if __name__ __main__保证模块可以被导入测试。9.4 运行与验证python spider.py运行成功后你会在同目录下看到output.csv文件。用文本编辑器或 Excel 打开内容是一组 JSON 字段和值的对应关系。如果运行失败按这个顺序排查看终端输出是连接超时还是 HTTP 错误。检查是否安装了 requests 库。把 URL 放到浏览器访问确认接口本身可用。确认网络环境能够访问目标地址。9.5 项目扩展点这个项目虽然简单但扩展方向很明确支持多页爬取在循环里改变页码参数。支持数据库存储把 CSV 换成 SQLite 或 MySQL。支持断点续爬记录已抓取的索引。支持多线程用线程池控制并发但要控制频率。10. 常见问题与排查思路爬虫项目的问题大多数都集中在请求、编码、解析和封禁四个方面。下面这张表是我见过的高频问题汇总。问题现象可能原因排查方式解决方案请求返回 403User-Agent 被识别为脚本查看请求头是否包含浏览器 UA补全 UA 和 Referer模拟浏览器返回 429请求过于频繁检查日志中的请求间隔增加随机延迟降低并发返回 HTML 但没有数据数据由 JS 动态加载抓包查看 XHR 请求直接请求数据接口解析结果为空CSS 选择器或 XPath 写错在浏览器 Console 中验证选择器调整解析表达式CSV 打开中文乱码编码不是 utf-8-sig查看文件编码使用 encodingutf-8-sig 写入请求超时网络不稳定或代理失效测试目标网站连通性增加超时秒数配置重试代理失效代理 IP 被目标网站封禁测试代理能否访问目标站更新代理池剔除失效代理App 抓不到包证书未信任或证书固定检查证书安装状态正确安装根证书必要时用专用工具遇到问题时先看错误类型再缩小范围。HTTP 状态码是 4xx 还是 5xx、是连接层面还是解析层面决定了排查方向完全不同。11. 最佳实践与工程建议最后一章聊一聊爬虫项目从“能运行”到“能维护”的建议。11.1 写日志不要用 print 排查小脚本用print没问题但项目一旦跑起来你不可能一直盯着终端。建议用logging模块输出带时间、级别的日志方便事后排查。11.2 配置和代码分离URL、请求头、延迟时间、代理列表这些都是配置不要硬编码在代码里。可以放到.env文件或 YAML 配置文件中让代码更通用。11.3 异常要分类捕获不要把except Exception一把梭。超时、连接错误、HTTP 错误、解析错误处理方式完全不同。分类捕获能让你知道系统在哪个环节出了问题。11.4 数据落库前先做去重重复数据会污染分析结果。在写入数据库前先基于唯一键做去重。11.5 尊重数据源的规则每次请求前先想清楚这个网站允许我这么访问吗我的请求会给对方服务器造成压力吗有没有官方 API 可以用11.6 控制并发量多线程、多进程确实能提升爬取速度但收益不是线性的。目标网站的风控强度、你的代理池规模、目标服务器的承受能力都限制了合理的并发上限。建议从 1 个线程开始逐步增加。11.7 增加监控与告警定时任务跑久了难免会遇到数据源改版、接口失效、代理耗尽的情况。建议在关键节点加上告警比如连续失败次数超过阈值就发消息通知而不是等到第二天发现数据全是空的。12. 总结与后续学习方向这篇文章从零开始梳理了 Python 网络爬虫的完整链路requests 请求、抓包定位接口、HTML/JSON 解析、常见反爬应对、代理池与防封策略最后用一个完整的项目代码把这些知识点串了起来。下一步你可以做三件事第一把文章里的示例代码跑一遍然后改造成你自己的目标。不建议直接复制别人的完整爬虫项目自己动手写一遍才能理解每个模块为什么要这样设计。第二深入学习抓包。找几个网站和 App用 F12 或 Fiddler 分析它们的请求结构练习快速定位数据接口。这个能力比会写一百个解析函数更有价值。第三学习数据库和调度框架。当爬虫数据量变大、任务变多时你会发现多线程、消息队列、定时调度、分布式爬虫这些方向都会成为新的瓶颈。爬虫的学习不是一锤子买卖而是持续解决问题的过程。先把这篇文章的基础打牢再往工程化方向走你会比曾经那个只会requests.get的自己强上不止一个台阶。