前言
在爬虫开发过程中,请求头(Request Headers)是模拟浏览器行为、突破网站反爬机制的核心要素。许多网站会通过校验请求头中的关键参数识别爬虫程序,直接返回错误响应或空白页面。本文将系统讲解爬虫请求头的构造逻辑,深度解析常见参数的作用与配置方法,并结合实战案例演示不同场景下请求头的定制策略,帮助开发者掌握请求头的核心配置技巧,提升爬虫的稳定性与成功率。
摘要
本文聚焦爬虫请求头的构造与参数解析,详细拆解User-Agent、Referer、Cookie、Accept等核心请求头参数的功能与配置规则,通过 **知乎热榜** 和 **淘宝商品搜索** 两个实战场景,演示基础请求头、带登录态请求头、反反爬请求头的构造方法。文中包含请求头参数对比表格、可直接运行的代码示例及请求结果分析,旨在帮助读者理解请求头的工作原理,掌握适配不同网站的请求头定制方案。
一、请求头的核心作用与基础原理
1.1 请求头的本质
请求头是 HTTP 请求中承载客户端信息的关键部分,用于告知服务器客户端的类型、请求来源、支持的内容格式、认证信息等。服务器通过解析请求头参数,判断请求的合法性与真实性:
- 合法浏览器请求的请求头包含完整的客户端标识、内容协商信息;
- 爬虫程序若未配置请求头,会暴露
Python-urllib/3.x、Scrapy/2.x等特征,被服务器直接拦截。
1.2 请求头的获取方式
开发者可通过浏览器开发者工具获取真实的请求头(以 Chrome 为例):
- 打开目标网页,按
F12进入开发者工具; - 切换至
Network标签,刷新页面; - 点击第一个请求(Doc 类型),在
Headers标签下查看Request Headers。
二、核心请求头参数解析
以下是爬虫开发中高频使用的请求头参数,按重要性排序解析:
| 参数名称 | 核心作用 | 取值示例 | 配置要点 |
|---|---|---|---|
| User-Agent(UA) | 标识客户端类型(浏览器 / 设备 / 系统) | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 | 模拟主流浏览器,避免使用 Python 默认 UA |
| Referer | 标识请求来源页面 | https://www.zhihu.com/(访问知乎热榜时) | 模拟正常跳转,避免直接访问目标 URL |
| Cookie | 存储用户登录态、会话信息 | SESSIONID=abc123; uid=123456; | 需从浏览器复制真实 Cookie,定期更新 |
| Accept | 声明客户端支持的响应内容格式 | text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 | 匹配服务器支持的格式,避免返回非预期内容 |
| Accept-Language | 声明客户端支持的语言 | zh-CN,zh;q=0.9,en;q=0.8 | 匹配网站主流语言,提升请求兼容性 |
| Accept-Encoding | 声明客户端支持的编码格式 | gzip, deflate, br | 减少响应数据体积,提升请求效率 |
| Connection | 声明连接方式 | keep-alive | 保持长连接,减少重复建立连接的开销 |
| Cache-Control | 声明缓存策略 | max-age=0 | 强制服务器返回最新数据,避免缓存 |
2.1 User-Agent:核心反爬识别参数
作用原理
User-Agent是服务器识别爬虫的首要依据,不同浏览器 / 设备的 UA 格式固定:
- Chrome 浏览器 UA:包含
Chrome/版本号、Windows NT/系统版本等信息; - Python 默认 UA:
Python-urllib/3.10(易被拦截)。
配置技巧
- 使用主流浏览器的 UA(如 Chrome、Firefox);
- 构建 UA 池,随机切换(应对 UA 封禁);
- 避免使用过于老旧的 UA 版本。
2.2 Referer:请求来源验证参数
作用原理
部分网站会校验Referer参数,确保请求来自站内跳转(如淘宝搜索需从淘宝首页跳转),若Referer为空或非站内域名,直接返回 403 错误。
配置技巧
- 目标 URL 为
https://s.taobao.com/search?q=手机时,Referer设为https://www.taobao.com/; - 若需模拟直接访问,可将
Referer设为空或目标网站根域名。
2.3 Cookie:登录态与会话保持参数
作用原理
Cookie存储用户的登录信息、会话 ID 等,爬取需要登录的页面(如知乎个人中心)时,必须携带有效 Cookie。
配置技巧
- 从浏览器开发者工具复制 Cookie(注意时效性,需定期更新);
- 避免 Cookie 中包含敏感信息(如密码);
- 结合
CookieJar管理多个 Cookie。
三、请求头构造实战案例
3.1 基础请求头构造(突破基础反爬)
场景:爬取知乎热榜页面
代码实现
python
运行
import urllib.request import urllib.error # 目标URL:知乎热榜 url = "https://www.zhihu.com/hot" # 构造基础请求头(模拟Chrome浏览器) 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/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive", "Cache-Control": "max-age=0" } try: # 构造Request对象,添加请求头 request = urllib.request.Request(url=url, headers=headers, method="GET") # 发送请求 response = urllib.request.urlopen(request, timeout=10) # 读取响应内容(知乎返回的是压缩数据,需解压) html = response.read().decode("utf-8") print("请求状态码:", response.getcode()) print("页面标题:", html.split("<title>")[1].split("</title>")[0]) print("页面内容前300字符:\n", html[:300]) except urllib.error.HTTPError as e: print("HTTP错误:", e.code, ",原因:", e.reason) except urllib.error.URLError as e: print("网络错误:", e.reason)输出结果
plaintext
请求状态码: 200 页面标题: 知乎热榜-知乎 页面内容前300字符: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <title>知乎热榜-知乎</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <link rel="icon" type="image/png" sizes="192x192" href="https://static.zhihu.com/heifetz/assets/favicon.ico"> <link rel="apple-touch-icon" sizes="180x180" href="https://static.zhihu.com/heifetz/assets/apple-touch-icon.png"> <link rel="mask-icon" color="#0084FF" href="https://static.zhihu.com/heifetz/assets/safari-pinned-tab.svg">原理解析
- 配置完整的基础请求头,模拟 Chrome 浏览器的请求特征,避开知乎的基础反爬机制;
Accept-Encoding设置为gzip, deflate, br,支持服务器返回压缩数据,提升请求效率;Cache-Control: max-age=0强制服务器返回最新的热榜数据,避免读取缓存内容。
3.2 带 Referer 的请求头构造(应对来源验证)
场景:爬取淘宝商品搜索页面(需验证 Referer)
代码实现
python
运行
import urllib.request import urllib.parse import urllib.error # 基础URL与参数 base_url = "https://s.taobao.com/search" params = { "q": "华为Mate60 Pro", "imgfile": "", "commend": "all", "ssid": "s5-e", "search_type": "item", "sourceId": "tb.index", "ie": "utf8", "initiative_id": "tbindexz_20170306" } # 编码参数并拼接URL encoded_params = urllib.parse.urlencode(params) full_url = f"{base_url}?{encoded_params}" # 构造带Referer的请求头 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", "Referer": "https://www.taobao.com/", # 模拟从淘宝首页跳转 "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive" } try: request = urllib.request.Request(url=full_url, headers=headers) response = urllib.request.urlopen(request, timeout=15) html = response.read().decode("utf-8") print("请求状态码:", response.getcode()) print("搜索结果页面长度:", len(html)) except urllib.error.HTTPError as e: print("HTTP错误:", e.code, ",原因:", e.reason) except urllib.error.URLError as e: print("网络错误:", e.reason)输出结果
plaintext
请求状态码: 200 搜索结果页面长度: 896542原理解析
- 淘宝搜索页面会校验
Referer参数,若未设置或设置为非淘宝域名,会返回 403 错误; - 将
Referer设为淘宝首页https://www.taobao.com/,模拟从首页点击搜索框的正常行为; - 完整的参数拼接 + 合规的请求头,确保请求被服务器判定为合法浏览器请求。
3.3 带 Cookie 的请求头构造(爬取登录后页面)
场景:爬取知乎个人主页(需登录态)
代码实现
python
运行
import urllib.request import urllib.error # 目标URL:知乎个人主页(需替换为实际的个人主页URL) url = "https://www.zhihu.com/people/your-username" # 构造带Cookie的请求头(Cookie需从浏览器复制) 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", "Cookie": "SESSIONID=abc123456789; _zap=12345678-1234-1234-1234-1234567890ab; d_c0=\"ABCDEFG==|1234567890\";", # 替换为真实Cookie "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", "Referer": "https://www.zhihu.com/" } try: request = urllib.request.Request(url=url, headers=headers) response = urllib.request.urlopen(request, timeout=10) html = response.read().decode("utf-8") print("请求状态码:", response.getcode()) # 提取用户名(验证是否登录成功) username = html.split("<span class=\"ProfileHeader-name\">")[1].split("</span>")[0] print("登录用户:", username) except urllib.error.HTTPError as e: if e.code == 401: print("Cookie失效,需重新登录获取") else: print("HTTP错误:", e.code, ",原因:", e.reason) except urllib.error.URLError as e: print("网络错误:", e.reason) except IndexError: print("未提取到用户名,可能Cookie无效或页面结构变更")输出结果(Cookie 有效时)
plaintext
请求状态码: 200 登录用户: 张三输出结果(Cookie 失效时)
plaintext
HTTP错误: 401 ,原因: Unauthorized原理解析
Cookie参数包含知乎的会话 ID、登录凭证等信息,服务器通过 Cookie 验证用户是否登录;- Cookie 具有时效性(通常几小时至几天),失效后需重新从浏览器复制;
- 401 状态码表示未授权,说明 Cookie 无效或已过期,需更新 Cookie 后重新请求。
四、请求头优化与反反爬策略
4.1 请求头池化(应对 UA/Cookie 封禁)
实现思路
构建多个不同的请求头(不同 UA、不同 Cookie),随机选择使用,避免单一请求头被封禁:
python
运行
import random # 构建UA池 ua_pool = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/121.0" ] # 构建Cookie池(需替换为真实有效Cookie) cookie_pool = [ "SESSIONID=abc123; _zap=123456;", "SESSIONID=def456; _zap=789012;" ] # 随机选择UA和Cookie headers = { "User-Agent": random.choice(ua_pool), "Cookie": random.choice(cookie_pool), "Referer": "https://www.zhihu.com/" }4.2 动态调整请求头(适配页面变化)
- 定期抓取浏览器最新的请求头,更新参数;
- 根据服务器返回的状态码调整请求头(如 403 时切换 UA/Cookie);
- 避免请求头参数过于固定,适当增加随机变化(如
Accept-Language添加小众语言)。
4.3 避免请求头冗余
- 无需配置所有参数,核心参数(UA、Referer、Cookie)优先配置;
- 避免添加错误的参数值(如
Accept-Encoding设置服务器不支持的编码); - 保持请求头格式与浏览器一致(如参数名大小写、值的格式)。
五、常见问题与解决方案
| 问题现象 | 原因分析 | 解决方案 |
|---|---|---|
| 返回 403 Forbidden | 请求头缺失核心参数(如 UA)或参数值异常 | 配置完整的浏览器请求头,替换为有效 UA |
| 返回 401 Unauthorized | Cookie 失效或未配置 | 重新从浏览器复制 Cookie,更新请求头 |
| 返回 503 Service Unavailable | 请求频率过高或 IP 被封禁 | 增加请求间隔,使用代理 IP,配合请求头池 |
| 页面内容为空 / 不完整 | 请求头参数不匹配(如 Accept 格式错误) | 复制浏览器的完整请求头,逐一校验参数 |
六、总结
请求头构造是爬虫开发中突破反爬机制的关键环节,核心在于模拟浏览器的请求特征,让服务器判定请求为合法访问。本文从参数解析、实战构造、优化策略三个维度,系统讲解了请求头的使用方法,重点强调了User-Agent、Referer、Cookie等核心参数的配置技巧。在实际开发中,需根据目标网站的反爬规则灵活调整请求头:基础反爬网站仅需配置核心参数,严格反爬网站需构建请求头池并结合代理 IP 使用。
同时,开发者需遵守网站的robots.txt协议和相关法律法规,合理控制请求频率,避免对服务器造成不必要的压力。掌握请求头的构造与优化方法,能显著提升爬虫的稳定性与通用性,为后续处理复杂反爬场景奠定基础。
注意事项:Cookie 包含用户敏感信息,请勿泄露或滥用;爬取需要登录的页面时,需确保符合网站的用户协议,避免违规操作。