ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Python爬虫零基础入门:从HTTP请求到数据解析存储的完整指南

2026/8/30 1:22:16 拓冰建站 浏览量
Python爬虫零基础入门:从HTTP请求到数据解析存储的完整指南 Python 爬虫在很多人看来是一个很酷的能力写一段代码程序就能自动抓取网页上的商品价格、新闻标题、行业数据。但真正上手以后很多人会卡在同一个地方——不是requests不会用而是不知道整个流程里每一步在做什么也不知道页面抓不下来时该检查什么。本文会从零开始带你把 Python 爬虫的完整链路走通环境搭建、HTTP 请求、HTML 解析、数据保存、翻页抓取、常见报错排查以及写爬虫之前必须想清楚的合规边界。文章不需要任何编程基础但建议按顺序操作不要跳着看。1. 先理解爬虫的完整链路再动手写代码1.1 爬虫与普通浏览器的区别爬虫本质上是一个自动化获取网页数据的程序。普通浏览器的工作方式是用户输入网址浏览器发送 HTTP 请求服务器返回 HTML 页面浏览器再把 HTML 渲染成视觉页面。爬虫的工作方式更直接程序发送 HTTP 请求拿到服务器返回的 HTML、JSON、图片等原始内容然后从这些原始内容中提取需要的数据。两者的核心差异在于“解析方式”。浏览器负责渲染爬虫负责提取。所以爬虫要处理的问题不是“页面长什么样”而是“页面数据放在哪个结构里”。难点通常集中在三个地方请求构造不正确服务器不返回数据。目标页面是动态渲染的HTML 里看不到真实数据。爬取频率过高触发网站的反爬机制。这三种问题会在后续章节分别展开。1.2 HTTP 请求与响应的基本过程Python 爬虫中最常用的 HTTP 方法是GET和POST。GET用于获取资源参数一般放在 URL 的查询字符串中适合翻页、搜索、筛选等场景。POST用于提交数据参数放在请求体中适合登录、表单提交、接口调用等场景。一个完整的 HTTP 响应包含状态行、响应头和响应体。对爬虫来说最关键的是两个部分状态码200表示成功403表示拒绝访问404表示页面不存在503表示服务不可用。响应体可能是 HTML、JSON、XML、图片二进制数据等。在编写爬虫时第一步永远是先看响应状态码再看响应内容。很多人一上来就写解析代码结果请求 403 或跳转到登录页解析自然全部失败。1.3 静态网页与动态网页决定技术选型静态网页的 HTML 中直接包含数据服务器返回什么浏览器就渲染什么。使用requests请求页面后用解析库提取内容即可。动态网页则是前端先加载一个 HTML 骨架再通过 JavaScript 异步请求后端接口获取数据最后动态渲染到页面上。直接请求 HTML 只能得到空壳真正数据在接口返回的 JSON 中。所以写爬虫之前要先打开浏览器开发者工具在 Network 面板观察页面加载过程如果数据在doc类型的请求响应里属于静态。如果数据在xhr或fetch类型的请求响应里属于动态接口。如果接口请求包含加密参数、签名、时间戳校验爬取难度会明显上升。对于学习阶段优先选择静态页面或公开 API 作为练习对象。等掌握基础流程后再研究动态接口。1.4 合规边界和 robots.txt爬虫不是“代码能跑就行”。在学任何技术之前先建立合规意识比学会某个解析库更重要。只抓取公开、允许访问的数据不采集账号信息、个人隐私、涉密内容。控制请求频率不把目标服务器拉垮。使用前先查看目标网站的robots.txt例如访问https://example.com/robots.txt查看允许和禁止的爬取路径。不绕过登录验证、不破解验证码、不伪造身份信息。抓取的数据用于学习、研究和正当商业分析时仍要遵守相关法律法规和网站服务条款。robots.txt是网站在协议层面给出的爬取许可声明不代表法律义务但遵守它是开发者的基本职业素养。本文所有示例都使用公开测试站点不指向任何真实业务系统。2. Python 环境准备先装好解释器和编辑器2.1 Python 版本选择与环境变量在开始写爬虫之前需要确定 Python 已经安装并且能正常使用。这里区分三种操作系统环境。操作系统建议安装方式关键点Windows官网下载安装包安装时勾选 Add Python to PATHmacOSHomebrew 安装或官网安装包注意系统自带 Python 版本可能偏低Linuxapt / yum 安装部分发行版默认只有 Python 3无pip需要单独安装如果原始安装包没有特别说明建议使用 Python 3.9 以上的稳定版本。学习爬虫不需要最新版本但 3.6 以下版本已经过老部分第三方库不再支持。安装完成后在终端或命令行执行验证python --version pip --version如果在 Windows 命令行中执行python提示找不到命令大概率是安装时没有勾选 Add Python to PATH。处理方式有两种重新安装并勾选或者手动把 Python 安装路径添加到系统环境变量 PATH 中。2.2 VSCode 与 PyCharm 怎么选VSCode 和 PyCharm 都能开发 Python 爬虫。对于零基础用户推荐原则很简单PyCharm Community Edition自带项目管理和调试功能对刚接触 Python 的人更友好不用关心太多配置文件。VSCode轻量、启动快需要手动安装 Python 扩展和选择解释器。如果选择 VSCode至少需要完成两件事在扩展市场安装 Python 扩展。按CtrlShiftP打开命令面板执行 Python: Select Interpreter选择刚才安装的 Python 解释器。在 VSCode 中新建.py文件并运行推荐配置好终端集成。一个常见坑是在 VSCode 里运行程序报“No module named requests”但在命令行里运行正常。这通常是因为 VSCode 选择的解释器不是当前虚拟环境中的 Python解决办法是在命令面板中重新选择解释器。2.3 创建虚拟环境并安装依赖爬虫项目建议使用虚拟环境避免不同项目的依赖相互污染。mkdir python-spider-demo cd python-spider-demo python -m venv venv激活虚拟环境Windowsvenv\Scripts\activatemacOS 或 Linuxsource venv/bin/activate激活后命令行前缀会出现(venv)此时再安装依赖。安装爬虫基础依赖pip install requests beautifulsoup4 lxml pandas各库的作用requests发送 HTTP 请求。beautifulsoup4解析 HTML 文档。lxml提供更快的 HTML/XML 解析引擎是 BeautifulSoup 的底层解析器之一。pandas把清洗后的数据整理成表格格式方便保存 CSV 或分析。2.4 环境检查清单在写第一行爬虫代码之前建议按以下清单检查环境[ ] 命令行执行python --version能输出版本号。[ ] 命令行执行pip --version能输出 pip 版本号。[ ] 已创建虚拟环境并激活。[ ] 已安装requests、beautifulsoup4、lxml。[ ] 在 Python 交互式环境中执行import requests不报错。3. 写第一个最小爬虫抓取公开页面并保存数据3.1 示例目标使用公开测试站点本节使用公开测试站点quotes.toscrape.com。该站点是专门的爬虫练习网站页面结构简单不包含敏感信息适合作为第一个完整案例。需求抓取首页的名言文字、作者和标签保存到本地 CSV 文件。3.2 使用 requests 发送第一个请求新建spider.py写入以下代码import requests url https://quotes.toscrape.com/ response requests.get(url, timeout10) print(response.status_code) print(response.text[:500])运行python spider.py如果输出200并且后面跟着 HTML 内容说明请求成功。这里有两个关键点timeout10表示 10 秒内没有响应就抛出超时异常。不写 timeout程序可能无限等待。response.text是解码后的字符串response.content是原始字节。解析 HTML 时通常用response.text下载图片时用response.content。3.3 使用 BeautifulSoup 解析 HTML在spider.py基础上扩展import requests from bs4 import BeautifulSoup url https://quotes.toscrape.com/ response requests.get(url, timeout10) response.encoding utf-8 soup BeautifulSoup(response.text, html.parser) quotes soup.select(.quote) for quote in quotes: text quote.select_one(.text).get_text() author quote.select_one(.author).get_text() tags [tag.get_text() for tag in quote.select(.tag)] print(text, author, tags)运行后可以看到每条名言、作者和标签列表。BeautifulSoup的select方法使用 CSS 选择器定位元素.quote表示 class 为 quote 的节点.text和.author同理。3.4 把数据保存成 CSV 文件使用标准库csv保存import csv import requests from bs4 import BeautifulSoup url https://quotes.toscrape.com/ response requests.get(url, timeout10) response.encoding utf-8 soup BeautifulSoup(response.text, html.parser) quotes soup.select(.quote) rows [] for quote in quotes: text quote.select_one(.text).get_text() author quote.select_one(.author).get_text() tags ,.join(tag.get_text() for tag in quote.select(.tag)) rows.append([text, author, tags]) with open(quotes.csv, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerow([名言, 作者, 标签]) writer.writerows(rows) print(保存完成共, len(rows), 条)注意编码使用utf-8-sig而不是utf-8。原因是 Excel 打开带 BOM 的 UTF-8 文件时能正确识别中文如果用普通utf-8Excel 可能出现乱码。3.5 运行验证和预期输出运行程序后工作目录下应该生成quotes.csv。用文本编辑器打开可以看到表头和 10 行左右的名言数据。验证步骤控制台能打印出状态码和保存条数。quotes.csv文件已创建。文件中的中文没有乱码。每行数据包含名言、作者、标签三列。注意不要只验证程序能启动还要验证文件里的数据是否完整、字段是否对齐、有没有空行或重复数据。4. Requests 核心用法从能跑到稳定4.1 常用参数速查表requests是 Python 爬虫使用频率最高的库。以下参数在真实项目中几乎都会用到。参数作用实例url请求地址requests.get(url)paramsURL 查询参数params{page: 2}headers请求头headers{User-Agent: ...}timeout超时时间timeout(5, 10)cookies携带 Cookiecookies{sessionid: ...}proxies代理配置仅在合规的网络环境按需配置verify是否校验 SSL 证书verifyFalse只在必要时使用allow_redirects是否自动跟随重定向allow_redirectsFalsetimeout可以只传一个数字也可以传一个元组分别表示连接超时和读取超时。4.2 Headers 伪装浏览器很重要很多网站会检查User-Agent。如果请求头中的User-Agent是 Python 默认值服务器可能直接返回 403。一个常见的请求头配置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,*/*;q0.8, Accept-Language: zh-CN,zh;q0.9,en;q0.8, }这里不是伪造身份去欺骗系统而是让请求看起来像普通浏览器访问。对于正常公开页面的采集这种操作处于常规开发范畴。设置User-Agent后需要观察响应状态码和响应内容是否发生变化。4.3 超时、重试与异常处理网络请求可能因为服务器繁忙、DNS 解析失败、连接重置等原因失败。单次请求必须放在异常处理中否则程序一旦遇到网络波动就会中断。import time import requests headers { User-Agent: Mozilla/5.0 } def fetch(url, max_retry3): for attempt in range(max_retry): try: resp requests.get(url, headersheaders, timeout10) if resp.status_code 200: return resp elif resp.status_code in (403, 404, 500): return resp except requests.RequestException as exc: print(f第 {attempt 1} 次请求失败: {exc}) time.sleep(2) return None这里使用max_retry控制重试次数使用time.sleep(2)在两次请求之间等待。重试不能无限进行否则在目标服务器异常时会让程序长时间卡住。4.4 Session 与 Cookie 的配合如果爬取过程中需要保持登录状态或者需要维持会话不要每次都新建requests.get建议使用requests.Session()。session requests.Session() session.headers.update(headers) login_data { username: your_username, password: your_password } resp session.post(https://example.com/login, datalogin_data, timeout10) print(resp.status_code) profile_resp session.get(https://example.com/profile, timeout10) print(profile_resp.text[:200])Session会自动保存服务器返回的 Cookie后续请求自动携带。不使用Session时Cookie 不会在多个请求之间自动传递。4.5 编码问题乱码的根源网页编码不统一是爬虫新手最常遇到的问题。常见情况有页面声明charsetutf-8但response.text默认按 HTTP 头里的编码解码可能错误。中文页面使用gb2312或gbk请求时未指定编码出现乱码。规范做法是先检查响应内容里的编码声明然后显式设置编码。response requests.get(url, timeout10) if response.encoding is None: response.encoding utf-8 text response.text更保险的方式是使用response.apparent_encoding让requests根据内容自动推断编码但该方式在某些页面会有额外性能开销。更推荐从 HTML 的meta charset...中找编码值再手动指定。5. 数据解析的三种主流方式5.1 正则表达式适合提取内容明确的片段正则表达式适合处理结构不规整、但内容模式明确的文本。例如从一段 HTML 中提取所有链接import re import requests resp requests.get(https://quotes.toscrape.com/, timeout10) text resp.text links re.findall(rhref(/[^]*), text) print(links[:10])正则表达式的优点是简单、直接、不需要额外库缺点是看不懂的人很难维护且遇到复杂嵌套结构时写起来很痛苦。在爬虫项目中建议把正则用于小范围提取而不是整个页面的主解析方式。5.2 XPath适合层级清晰的 HTMLXPath 是一种在 XML/HTML 文档中查找信息的语言使用/和//描述节点层级关系。使用lxml的etree模块可以方便地执行 XPathfrom lxml import etree import requests resp requests.get(https://quotes.toscrape.com/, timeout10) resp.encoding utf-8 tree etree.HTML(resp.text) authors tree.xpath(//small[classauthor]/text()) print(authors[:5])//small[classauthor]/text()的含义是查找所有class属性为author的small节点并取其文本内容。XPath 功能很强支持按属性、文本、位置、包含关系筛选节点适合结构相对稳定的页面。5.3 CSS 选择器和 BeautifulSoup、lxml 一起用CSS 选择器比 XPath 更接近前端开发者的习惯。BeautifulSoup 的select方法直接支持 CSS 选择器。from bs4 import BeautifulSoup with open(page.html, r, encodingutf-8) as f: html f.read() soup BeautifulSoup(html, lxml) items soup.select(div.quote span.text) for item in items: print(item.get_text())CSS 选择器常见的符号.class按 class 选择。#id按 id 选择。div p后代选择器。div p直接子元素选择器。5.4 三种方式的选型对比解析方式学习成本可维护性适用场景正则表达式中等较低提取邮箱、手机号、ID 等固定模式XPath中等较高层级清晰的 HTML/XML 页面CSS 选择器较低较高与 BeautifulSoup 配合页面结构稳定实际项目中经常组合使用用 CSS 选择器定位外层节点用 XPath 处理复杂属性过滤用正则清理文本中的空白和多余符号。6. 从单页爬虫到批量、增量和垂直爬虫6.1 批量型爬虫的实现思路批量型爬虫适合“一次性把某个范围内的数据全部抓完”的场景。实现核心是翻页。quotes.toscrape.com的翻页 URL 形如/page/2/可以构造循环import requests from bs4 import BeautifulSoup base_url https://quotes.toscrape.com/page/{}/ for page in range(1, 6): url base_url.format(page) resp requests.get(url, timeout10) if resp.status_code ! 200: print(页面请求失败:, url) break soup BeautifulSoup(resp.text, html.parser) quote_count len(soup.select(.quote)) print(f第 {page} 页抓到 {quote_count} 条数据)翻页时要注意停止条件。有些网站的最后一页会返回空数据有些会返回 404有些使用 AJAX 加载无法直接用页码拼接。建议每一轮循环都判断数据量如果当前页解析结果为空就提前结束。6.2 增量型爬虫的更新策略增量型爬虫的核心是“只爬取新增或变化的数据”。常见策略有三种时间戳增量记录上次爬取时间只抓取该时间之后发布的内容。去重增量把已抓取数据的唯一标识存入数据库或集合每次解析后判断是否已存在。列表页增量先抓列表页再比对已抓数据只进入详情页处理新增项。最小去重实现seen set() def is_duplicate(quote_id): if quote_id in seen: return True seen.add(quote_id) return False真正的增量爬虫需要持久化存储推荐使用 SQLite、MySQL 或 Redis。只把去重集合放在内存中程序重启后会全部丢失。6.3 垂直型爬虫的场景拆解垂直型爬虫专注于某一特定领域比如只抓图书信息、电影评分、二手车报价或行业新闻。它的好处是目标明确解析规则可以做到很精确坏处是目标网站改版后需要及时调整解析逻辑。垂直型爬虫通常按以下步骤拆解确定数据字段商品标题、价格、销量、发布时间等。确定数据来源列表页、详情页、搜索接口。确定更新频率每小时、每天还是每周。确定存储方案CSV、Excel、数据库。加入监控程序失败时要能通过日志或通知发现问题。6.4 学会构造翻页参数别手动复制几十个链接很多网站的翻页参数不是简单的数字而是offset、cursor、page_size等。构造请求时要先观察 URL 变化规律。例如某个接口 URL 为params { page: page, page_size: 20, sort: time, } resp requests.get(https://example.com/api/list, paramsparams, timeout10) data resp.json()通过params传参比手动拼接 URL 更安全requests会自动处理特殊字符编码。注意如果翻页过程中发现返回的数据始终一样优先检查参数是否真的生效其次检查请求是否携带了必要的 Cookie 或 Token。7. 常见报错现象与排查路径7.1 403 Forbidden 与 UA 校验现象请求返回 403浏览器可以正常打开。原因服务器检测到请求来自非浏览器客户端最常见的原因是User-Agent缺失或不标准。检查方式resp requests.get(url, timeout10) print(resp.status_code) print(resp.request.headers)解决设置完整浏览器请求头特别是User-Agent、Accept、Accept-Language。如果设置了浏览器请求头仍然 403需要进一步检查是否缺少 Cookie、是否被风控拦截、是否有必要的 Referer 字段。7.2 SSL 证书校验失败现象报错requests.exceptions.SSLError或ssl.SSLCertVerificationError。原因目标网站证书链不完整、证书过期、或本地环境缺少根证书。排查路径先更新系统证书。再检查是不是代理或网络环境导致证书校验异常。确认目标网站本身证书是否有效。在学习和调试阶段可以临时指定verifyFalseresp requests.get(url, timeout10, verifyFalse)但这样做会跳过证书校验存在中间人攻击风险。生产环境不建议使用。verifyFalse时还会出现InsecureRequestWarning警告可以通过以下方式抑制import urllib3 urllib3.disable_warnings()7.3 返回 JSON 却解析失败现象调用接口返回了一段类似 JSON 的文本但response.json()报JSONDecodeError。原因接口返回的实际是 HTML 报错页、登录跳转页或者内容被压缩。排查方式先把响应文本打印出来看前 500 字符。检查 HTTP 状态码。检查响应头中的Content-Type。检查是否有Content-Encoding: gzip而requests没有自动解压。绝大多数情况下不要把response.json()当作必定成功的方法先判断内容类型再解析。7.4 被限制访问频率怎样科学降速现象前几页正常翻到后面开始出现 429 Too Many Requests然后被临时封禁。原因请求频率过高。解决方式import time import random time.sleep(random.uniform(1, 3))真实项目还需要考虑使用单线程串行请求避免瞬间并发过高。对同一域名做全局频率控制。使用日志记录每次请求的时间和状态码。请求失败时退避等待不要立即重试。7.5 排查优先顺序爬虫报错时按以下顺序排查响应状态码是多少是否 403、404、429、503。响应内容是否是预期页面先打印resp.text[:500]。URL 是否正确参数是否生效请求头是否完整User-Agent、Cookie、Referer。数据是否在接口而不是 HTML 中动态页面需要找 XHR 请求。解析规则是否选择正确页面结构变化会导致解析不到数据。是否受到限流检查请求频率和时间间隔。8. 写爬虫前建议先想清楚的五件事8.1 请求前检查在写代码前先手动访问目标页面确认以下几点[ ] 页面是否存在内容是否公开。[ ]robots.txt是否禁止爬取。[ ] 数据是在 HTML 中还是接口中。[ ] 列表页和详情页的 URL 规律。[ ] 请求需要哪些请求头参数。这些检查能避免写好代码后发现方向错误浪费时间。8.2 数据存储与去重学习阶段可以用 CSV 保存数据但生产环境需要更完整的设计。推荐以下分层原始数据保存为 JSON 或存入数据库保证后续重新解析不丢失。添加唯一标识字段抓取前先查重。定期做数据备份。清洗和解析逻辑与请求逻辑分离避免一个文件全部堆在一起。8.3 异常和日志爬虫程序最怕的不是报错而是“不知道报错”。建议从一开始就添加日志import logging logging.basicConfig( levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(spider.log, encodingutf-8), logging.StreamHandler() ] ) logging.info(开始请求: %s, url) logging.warning(请求失败: %s, exc)日志至少包含时间、请求 URL、状态码、异常信息、解析条数。这样程序跑偏时能快速定位发生时间点。8.4 代码结构与可维护性几行代码的爬虫可以写在一个文件里。当爬虫规模变大建议按模块拆分spider-project/ main.py # 入口和控制逻辑 spider/request.py # 请求层 spider/parse.py # 解析层 spider/storage.py # 存储层 config.py # 配置项如 URL、请求头、频率请求、解析、存储分离后改版时只需要修改对应模块不会牵一发动全身。8.5 从爬虫到数据可视化的学习路径爬虫只是数据流程的第一步。抓下来的数据还需要清洗、统计和展示。学完本文后可以按以下路径继续用pandas清洗数据处理缺失值和重复值。用matplotlib或pyecharts制作可视化图表。学习scrapy框架处理更复杂的请求调度和扩展机制。学习数据库操作把数据写入 MySQL 或 SQLite。给自己的爬虫程序加日志、异常重试、配置外置化。热搜词里出现的 Python 安装、VSCode 配置、requests 爬虫、数据可视化等内容本质上都是这一条学习路径上的节点。每一个点单独看都不难合在一起才构成完整的爬虫工程能力。收尾给新手的练习建议学习爬虫最容易犯的错误是“看会了但写不出来”。看十段视频不如自己抓一个页面。建议按以下顺序练习抓一个静态列表页把标题和链接保存到 CSV。给程序加上翻页抓取前 5 页数据。给程序加上异常处理和重试机制故意把timeout改小观察日志输出。找一个公开接口用response.json()解析 JSON 数据。把抓到的数据导入 pandas做一次简单的统计。当你能独立完成这五步Python 爬虫的基础链路就算真正打通了。下一步再进入 Scrapy、动态页面渲染、分布式爬虫等进阶方向时你会发现自己已经具备拆解问题和排查问题的能力。技术工具会不断更新但“先观察页面、再构造请求、再解析数据、再做好异常处理”这条主线在大多数爬虫项目中都不会变。