Requests发起请求返回403或空响应,根本原因是服务端识别出爬虫并拦截,需设置完整请求头(User-Agent、Accept、Accept-Language等)模拟真实浏览器,必要时配合代理IP、随机延时及Session保持上下文。

Requests发起请求时遇到403或空响应怎么办
多数网站默认拒绝爬虫,直接 requests.get() 会返回 403 或空内容。这不是代码写错了,而是服务端拦截了无特征的请求头。
必须手动设置 User-Agent 和其他常见 headers,模拟真实浏览器行为:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
- 只加
User-Agent不够,部分站点还会检查Accept、Accept-Language,建议复制浏览器开发者工具 Network 标签页里的完整请求头 - 某些页面依赖 JavaScript 渲染,
requests拿不到最终 HTML —— 这时候不能硬刚,得换Selenium或Playwright - 遇到重定向后内容为空?检查
response.history,确认是否被跳转到登录页或风控页
BeautifulSoup解析时找不到元素的常见原因
BeautifulSoup 找不到你写的 select() 或 find() 目标,大概率不是 selector 写错,而是 HTML 结构和你 inspect 看到的不一致。
浏览器开发者工具里看到的 DOM 是 JS 渲染后的结果,而 requests 获取的是原始 HTML —— 两者常有差异。
立即学习“Python免费学习笔记(深入)”;
- 先打印
response.text[:500],确认实际返回的 HTML 是否包含你要找的标签 - 用
soup.find_all("div")看看顶层结构,再逐步缩小范围,别一上来就写复杂 CSS 选择器 - 注意 class 名含空格或动态生成(如
class="item item-123"),用[class*="item"]比死写全名更稳 - 如果目标在
<script>标签里(比如 JSON 数据),别用select(),改用find("script", string=re.compile(...))
处理中文乱码与编码自动识别失效
中文网页经常出现 字符,根本原因是 requests 没正确识别响应编码,导致 response.text 解码错误。
别依赖 response.encoding 自动推断 —— 它经常猜错,尤其对没有 charset 声明的 GBK 页面。
- 优先显式指定编码:
response.content.decode("gbk")(适用于国内老站)或response.content.decode("utf-8", errors="ignore") - 用
chardet.detect(response.content)["encoding"]探测,但注意它可能不准,建议只作参考 - 构造
BeautifulSoup时传入原始 bytes 更可靠:BeautifulSoup(response.content, "html.parser"),避免先 decode 再 encode 的二次损伤
分页与反爬节奏控制的实际操作
批量抓取多页时,不加控制容易被封 IP。这不是“加个 delay 就行”,关键在于节奏匹配目标站的真实用户行为。
- 别用固定
time.sleep(1)—— 真实用户翻页间隔是随机的,用time.sleep(random.uniform(1.5, 4)) - 分页 URL 不一定是
?page=2,注意观察是否有 token、timestamp、sign 参数,漏掉会导致后续请求 403 - 每次请求后检查
response.status_code和关键字段是否存在,失败时记录日志并暂停,而不是直接报错退出 - 本地测试阶段务必加
session.headers.update(...)复用 headers,避免每次新建 request 对象丢失上下文
真正麻烦的从来不是语法,而是每个网站自定义的响应逻辑和隐藏约束——多看 response.raw、少信浏览器渲染结果,才能避开大多数“明明 selector 对了却拿不到数据”的坑。


















