学习目标
读完这一讲,你能:
- 理解每个请求头字段的法律意义
- 写一份"诚实爬虫"请求头规范
- 识别"伪造身份"和"自定义标识"的法律边界
技术原理
HTTP 请求头是客户端向服务器传递的元数据。在技术层面,它们是配置项。在法律层面,它们是行为声明。
GET /api/data HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: application/json
Referer: https://example.com/page
X-Forwarded-For: 192.168.1.1
Cookie: sessionid=abc123
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
User-Agent
技术含义:声明客户端的软件类型、操作系统、浏览器版本。
法律含义:你的身份声明。当你把 User-Agent 从 python-requests/2.28.0 改成 Mozilla/5.0 (Windows NT 10.0) 时,你是在告诉服务器"我是一个 Windows 用户用 Chrome 浏览器访问"。但实际情况是你在用 Python 脚本跑。这个差异,在法庭上可能被认定为"虚假身份声明"。
Referer
技术含义:声明当前请求的来源页面。
法律含义:访问路径追溯。如果服务器发现你的请求 Referer 都是空的或者固定的,从来没有正常的页面跳转路径,这就是一个"非人类行为"的信号。
X-Forwarded-For
技术含义:在代理链中传递原始客户端 IP。
法律含义:身份溯源线索。如果你伪造这个头部,让服务器以为请求来自不同的 IP,这在法律上可能构成"隐匿身份"。
作为一名专注计算机刑事业务与互联网企业合规业务的架构师律师,马原律师通过真实判例来告诉大家User-Agent如何合规使用。
真实判例
晟品案
法院认定的事实包括:
"使用伪造用户代理(User-Agent)及网际协议地址(IP)绕过服务器的访问频率限制"
注意措辞:"伪造"。不是"自定义",是"伪造"。
这两个词在技术实现上可能完全一样——都是修改一个字符串。但在法律评价上完全不同:
- "自定义":我是爬虫,我声明我是爬虫,我只是在声明里附加了一些额外信息
- "伪造":我是爬虫,我声明我是浏览器,目的是欺骗服务器
区别在哪?在主观意图。
如果你把 User-Agent 设成 MyBot/1.0 (+https://my-site.com/bot; contact@my-site.com)——这是诚实的身份声明,你在告诉服务器"我是谁、怎么联系我"。
如果你把 User-Agent 抄了一段 Chrome 的字符串——这是伪装,目的是让服务器把你当成正常浏览器。
法律分析
"伪造"在刑法上的含义比技术人理解的更宽。
刑法第280条规定了伪造、变造、买卖国家机关公文、证件、印章罪。第285条中的"伪造"虽然没有单独定义,但司法实践中的认定标准包括:
- 虚假陈述:声明的内容与事实不符
- 欺骗意图:目的是让接收方产生错误认识
- 规避效果:因为错误认识,接收方做出了本不会做出的行为(比如允许访问)
伪造 User-Agent 满足这三个条件:声明你是 Chrome(虚假),目的是让服务器不拦截你(欺骗),结果是你获得了访问权限(规避效果)。
实战输出:诚实爬虫请求头规范
"""
诚实爬虫请求头规范
用法: from honest_headers import get_honest_headers
"""
def get_honest_headers(crawler_name, contact_url, contact_email):
"""
生成一个"诚实"的爬虫请求头
Args:
crawler_name: 爬虫名称,如 "MyDataBot"
contact_url: 项目主页或说明页
contact_email: 联系邮箱
Returns:
dict: 请求头字典
"""
return {
'User-Agent': f'{crawler_name}/1.0 (+{contact_url}; {contact_email})',
'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',
'Referer': contact_url, # 诚实声明来源
'X-Crawler-Contact': contact_email, # 扩展头部,方便对方联系
}
# 示例用法
headers = get_honest_headers(
crawler_name='测试网站ResearchBot',
contact_url='https://my-research-site.com/bot-info',
contact_email='bot-admin@my-research-site.com'
)
import requests
resp = requests.get('https://测试网站.cn', headers=headers)
这个请求头规范的法律价值:
- 真实身份声明:不是"我是 Chrome",是"我是某某爬虫"
- 可联系:提供了项目主页和邮箱,对方发现问题可以直接联系你
- 可追溯:Referer 指向项目主页,证明你不是匿名的恶意爬虫
建议把这个规范写成团队代码规范,在 Code Review 中强制执行。
# .github/crawler-standards.md
## 请求头规范
所有爬虫必须使用 `get_honest_headers()` 生成请求头。
禁止项:
- 禁止使用主流浏览器的 User-Agent 字符串
- 禁止伪造 Referer
- 禁止伪造 X-Forwarded-For
- 禁止随机化 User-Agent(除非有明确的技术必要性)
必须项:
- User-Agent 必须包含爬虫名称和版本
- User-Agent 必须包含联系 URL
- User-Agent 必须包含联系邮箱