做爬虫的人,多少都遇到过这样的情况:明明代码写对了,URL也没错,可一请求就返回403,或者干脆被重定向到验证码页面。你可能没意识到,问题出在请求头上。
为什么需要模拟HTTP请求头
浏览器访问网页时,会自动带上一堆信息,比如你是用Chrome还是Safari,操作系统是什么,甚至能告诉服务器你屏幕有多大。这些信息打包在一起,就是HTTP请求头(Request Headers)。
而默认的爬虫请求,比如用Python的requests库直接get,发出的请求太“干净”了。服务器一看:哪有人访问网页不带User-Agent的?八成是机器人。于是直接拦截。
举个生活化的例子:你去一家网红餐厅吃饭,门口保安看你是正常打扮、手里还拿着手机查点评APP,就放你进去了;但如果你穿着奇怪、一句话不说、眼神呆滞地站着,大概率会被拦下问一句‘你干嘛的?’。爬虫也一样,得穿得像个人,才能混进去。
常见的请求头字段
最常用的是这几个:
- User-Agent:说明浏览器和系统类型
- Referer:表示你从哪个页面跳过来的
- Accept:告诉服务器我能接收什么格式的内容
- Accept-Encoding:支持的压缩方式
- Accept-Language:偏好的语言
其中User-Agent最关键。很多网站靠它判断是不是常见浏览器。
怎么设置请求头
以Python为例,requests库可以轻松添加自定义头:
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",
"Referer": "https://www.google.com/",
"Accept-Language": "zh-CN,zh;q=0.9"
}
response = requests.get("https://example.com", headers=headers)
print(response.text)
这段代码发出的请求,看起来就跟一个用Chrome的普通用户差不多了。
别只用一个User-Agent
有些新手写爬虫,设了个User-Agent就以为万事大吉,结果跑一会儿又被封。原因可能是:你一直用同一个UA,行为太规律。
真实用户群体里,有人用Mac,有人用安卓手机,浏览器也不一样。你可以准备一组常见的User-Agent,每次请求随机选一个:
ua_list = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15"
]
import random
headers["User-Agent"] = random.choice(ua_list)
这样更像真实的流量混合,降低被识别的风险。
别忘了Referer
有些图片或接口资源,会检查Referer。比如你直接请求一张图,但Referer是空的,服务器可能拒绝返回。加上从搜索页或主页跳过来的Referer,反而能顺利下载。
比如你要抓电商网站的商品图,可以设置Referer为该商品的搜索列表页,就像用户先搜再点进去一样。
别过度伪装
有些人为了绕过检测,把请求头堆得特别长,连Cookie、X-Requested-With、Sec-Fetch-Mode全加上。其实没必要,搞得太复杂反而容易露馅。
记住:目标不是完美模仿,而是足够像人。大多数情况下,一个合理的User-Agent + 少量其他头就足够了。
爬虫的本质是技术对抗,但最好的策略往往是低调行事。把请求头处理好,你的爬虫就能少撞墙,多拿数据。