直接用requests.get()会被封,因默认User-Agent为python-requests/2.xx,服务器识别为爬虫而返回403或空响应;需设置随机User-Agent、补全Accept等请求头、添加随机延时(如time.sleep(random.uniform(1,3)))并避免固定节奏。

为什么直接用 requests.get() 会被封?
因为默认的 User-Agent 是 python-requests/2.xx,服务器一抓一个准。很多站点(比如知乎、豆瓣、新闻站)会直接返回 403 或空响应,甚至把 IP 加入临时黑名单。
解决思路不是“伪装得像人”,而是让请求看起来更接近真实浏览器行为:带合理请求头 + 不高频连发。
-
User-Agent必须换,且最好轮换(单个 UA 用多了也会被盯上) -
Accept、Accept-Language、Referer这几个字段补全后,通过率明显提升 - 延时不能固定(比如统一
time.sleep(1)),否则仍是规律性请求,容易被识别为脚本
怎么构造一套可用的随机请求头?
硬写死几个 UA 字符串再随机选,不如用现成的轻量库 fake-useragent,它自动从在线源更新主流浏览器 UA,避免自己维护过期列表。
注意:首次运行会联网拉取数据,后续缓存到本地;如果内网或不想联网,可改用静态列表方式兜底。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
立即学习“Python免费学习笔记(深入)”;
- 安装:
pip install fake-useragent - 基础用法:
from fake_useragent import UserAgent; ua = UserAgent(); headers = {"User-Agent": ua.random} - 生产环境建议加异常捕获,防止 UA 源不可用导致整个爬虫崩掉:
try: ua = UserAgent() except: ua = UserAgent(use_cache_server=False, path="ua.json") - 别只设
User-Agent,补全常用字段更稳:{"User-Agent": ua.random, "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive"}
随机延时该用 time.sleep() 还是异步?
对单线程小规模爬取(比如每天抓几百页),用 time.sleep() 最简单可靠;别碰 asyncio 或 aiohttp —— 增加复杂度但不解决反爬本质问题,还可能因并发控制不当触发风控。
- 推荐范围:
time.sleep(random.uniform(1, 3)),避开整数秒(如 1/2/3 秒)这种明显机器节奏 - 延时必须放在每次请求之后(不是之前),否则首请求仍可能被限流
- 如果目标站有明确速率限制(如 X-RateLimit-Limit),优先读响应头里的
Retry-After字段,比盲目 sleep 更精准 - 不要在重试逻辑里叠加延时(比如第 3 次失败才 sleep),应该每次请求后都 sleep,保持节奏稳定
真实项目中容易漏掉的三个点
很多人写了 UA 和 sleep 就以为万事大吉,结果跑两天就被封,往往卡在这三处:
- 没处理
Cookies:登录态、CSRF token、访问痕迹都存在 Cookie 里,光换 UA 不带 Cookie,某些页面直接 302 跳转或返回验证码 - 忽略
Referer:比如从列表页进详情页,Referer应该是列表 URL,空值或错值会触发校验 - HTTPS 证书验证没关(仅测试):
requests.get(..., verify=False)临时绕过证书错误,但上线前必须删掉,否则可能被中间人劫持或 SSL 握手失败
反爬不是拼参数数量,而是观察目标站实际拦截逻辑——先手动用浏览器开发者工具看它发了哪些头、有没有 JS 生成的签名、是否依赖 sessionStorage。UA 和延时只是最基础的门槛,跨过去之后,真正的难点才开始。

















