3、请求头分析与伪造:HTTP请求头结构、关键字段的检测与伪造
大家好,我是你们的老朋友。今天我们来聊聊请求头。
说实话,在搜索引擎安全这个领域摸爬滚打这么多年,我见过太多人栽在请求头上。你以为你伪装得很好,结果人家一看请求头就露馅了。反过来,你如果能把请求头玩明白了,绕过一些简单的检测,其实并不难。
这一节,我们就来拆解一下HTTP请求头。我会结合我自己的实战经验,带你看看Referer、Cookie、User-Agent这三个关键字段到底该怎么检测,又该怎么伪造。
3.1 HTTP请求头结构:别小看这几行文本
HTTP请求头,说白了就是客户端发给服务器的一组“自我介绍”。服务器通过它来判断你是谁、从哪里来、想干什么。
一个标准的HTTP请求头长这样:
GET /search?q=python HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml
Accept-Language: zh-CN,zh;q=0.9
Accept-Encoding: gzip, deflate, br
Referer: https://www.google.com/
Cookie: session_id=abc123; user_token=xyz789
Connection: keep-alive
嗯,看起来挺长,但核心就几行。我个人的习惯是,先看三样东西:User-Agent、Referer、Cookie。这三样是反作弊系统最常盯着的。
核心要点:请求头中的每一行,都可能成为反作弊系统的“指纹”。你改一个字符,可能就暴露了。
3.2 关键字段的检测与伪造
3.2.1 Referer:你从哪里来?
Referer字段告诉服务器,你是从哪个页面跳转过来的。比如你从百度点了一个链接,Referer就是百度的地址。
反作弊系统怎么用它?很简单——检查来源是否合法。
举个例子。我在项目中遇到过这样一个场景:某个搜索引擎的搜索接口,只允许来自自家搜索页面的请求。如果你直接通过程序调用,Referer是空的,或者是个乱七八糟的地址,那就会被直接拦截。
检测方式:
- 检查Referer是否为空
- 检查Referer是否包含特定域名
- 检查Referer的路径是否合法
伪造方式:
说白了,就是改一下请求头里的Referer值。比如:
import requests
url = "https://api.example.com/search"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Referer": "https://www.example.com/search?q=python"
}
response = requests.get(url, headers=headers)
print(response.text)
你看,就这么简单。但要注意,有些系统会校验Referer的格式和内容。我曾经见过一个系统,它要求Referer必须包含一个动态的token,这就比较麻烦了。
小技巧:伪造Referer时,最好先抓包看看正常请求的Referer长什么样。别自己瞎编一个,容易被识破。
3.2.2 Cookie:你的身份凭证
Cookie是服务器留在你浏览器里的小文件,用来记住你的登录状态、浏览记录等。反作弊系统非常依赖Cookie。
为什么?因为Cookie很难伪造。你想想看,一个正常的用户,他的Cookie是经过多次交互后累积下来的。而一个爬虫程序,它的Cookie往往是空的,或者只有几个固定的值。
检测方式:
- 检查Cookie是否为空
- 检查Cookie中的关键字段(如session_id)是否存在
- 检查Cookie的过期时间是否合理
- 检查Cookie的签名是否合法
伪造方式:
嗯,这里要注意。伪造Cookie不是简单地塞几个键值对就行。你需要先了解目标系统的Cookie生成逻辑。
我举个例子。有一次我需要爬取某个论坛的数据,它的反爬虫机制就是检查Cookie中的“user_token”。这个token是登录时服务器下发的,而且每次请求都会变化。怎么办?
我的做法是:先模拟登录,拿到有效的Cookie,然后在后续请求中带上它。
import requests
# 先登录,获取Cookie
login_url = "https://example.com/login"
login_data = {"username": "test", "password": "123456"}
session = requests.Session()
session.post(login_url, data=login_data)
# 现在session里已经自动保存了Cookie
response = session.get("https://example.com/profile")
print(response.text)
你看,用Session对象,它会自动帮你管理Cookie。但有些系统会检测Cookie的完整性,比如检查是否缺少某个字段。这时候你就得手动补全。
警告:千万不要直接复制别人的Cookie来用。Cookie通常绑定IP、User-Agent等信息,换了环境就会失效。我曾经见过有人因为用了别人的Cookie,结果被系统判定为账号异常,直接封号了。
3.2.3 User-Agent:你的浏览器身份
User-Agent(简称UA)告诉服务器,你用的是哪种浏览器、什么版本、什么操作系统。反作弊系统通过UA来判断你是不是一个真实的浏览器。
为什么UA重要?因为爬虫程序通常不会设置UA,或者设置一个很奇怪的UA。比如:
User-Agent: python-requests/2.28.1
这种一看就是爬虫。服务器看到这种UA,直接拒绝访问。
检测方式:
- 检查UA是否为空
- 检查UA是否包含常见的爬虫标识(如python-requests、curl、wget)
- 检查UA的格式是否合法
- 检查UA的版本号是否合理
伪造方式:
说白了,就是换一个正常的浏览器UA。比如:
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"
}
但要注意,有些系统会检测UA的完整性。比如,它要求UA必须包含“Mozilla”、“AppleWebKit”、“Safari”等关键字。你少一个,它就觉得不对劲。
避坑指南:我曾经因为UA版本号太新而被拦截过。当时我用了Chrome 130的UA,但那个系统只支持到Chrome 120。后来我改成120,就通过了。所以,伪造UA时最好用主流版本,别用太新的。
3.3 实战:绕过简单的请求头检测
好了,理论讲完了,我们来点实战。假设有一个网站,它只允许来自百度搜索的请求,而且要求UA必须是Chrome浏览器。
我们怎么绕过?
第一步,分析它的检测逻辑。我一般会先发一个正常的请求,看看返回什么。如果返回403,说明被拦截了。然后我再看错误信息,有时候它会告诉你“Referer不合法”或者“UA不合法”。
第二步,伪造请求头。根据分析结果,我们伪造Referer和UA:
import requests
url = "https://target.com/search"
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.baidu.com/s?wd=python"
}
response = requests.get(url, headers=headers)
print(response.status_code)
print(response.text[:200])
第三步,测试。如果返回200,说明绕过了。如果还是403,那就得继续分析,看看是不是还有其他检测点。
实战要点:
- 先抓包,看正常请求的请求头长什么样
- 逐字段对比,找出哪些字段被检测了
- 伪造时尽量模仿真实用户,别太刻意
- 如果一次不行,就多试几次,调整策略
说实话,绕过简单的请求头检测并不难。难的是那些结合了行为分析、IP检测、Cookie签名的复杂系统。但不管多复杂,请求头始终是第一步。你把这一步做好了,后面的路就好走多了。
好了,这一节就到这里。下一节我们会聊聊IP代理与指纹识别,到时候我会分享一些更高级的绕过技巧。咱们下次见。