跳转至

HTTP 响应、状态码与 Content-Type

HTTP 是无状态的应用层协议。一次网页抓取至少要区分:请求的 URL、响应状态码、响应头与响应内容。不要把“拿到了 200”直接等同于“拿到了正确的网页”。

1. 先看状态码,再处理内容

常见状态码类别:

类别 含义 抓取程序的基本处理
2xx 成功 再检查内容类型和页面结构
3xx 重定向 记录最终 URL;不要无限跟随
4xx 客户端错误 停止该 URL,检查地址、权限或访问规则
5xx 服务端错误 暂停或低频重试,避免增加站点负担

在 Requests 中,raise_for_status() 会对 4xx5xx 响应抛出异常:

import requests

response = requests.get("https://example.com/", timeout=10)
response.raise_for_status()

2. 检查 Content-Type

Content-Type 描述响应表示的媒体类型。HTML 常见为 text/html,JSON 常见为 application/json。抓取 HTML 前先检查它,能尽早发现下载到 PDF、图片、错误页或接口数据的情况。

content_type = response.headers.get("Content-Type", "").lower()
if "text/html" not in content_type:
    raise ValueError(f"预期 HTML,实际得到:{content_type}")

媒体类型可以带参数,例如 text/html; charset=utf-8,所以通常判断是否包含 text/html,不要直接做完整字符串相等比较。

3. 重定向不是失败,但要可追踪

Requests 对 GET 默认跟随重定向。最终地址在 response.url,中间响应在 response.history。对来源记录或去重,优先保存最终规范 URL,同时保留原始 URL 以便追溯。

response = requests.get("https://example.com/old-page", timeout=10)
print("最终地址:", response.url)
print("重定向次数:", len(response.history))

如果任务必须确认某个地址是否发生跳转,可用 allow_redirects=False;不要通过无限跳转链继续访问异常站点。

4. 建议的最小校验顺序

  1. 请求设置超时。
  2. 调用 raise_for_status()
  3. 检查 Content-Type 是否符合预期。
  4. 保存 response.url,再交给 HTML 或 JSON 解析器。
  5. 解析后检查必填字段,避免把站点错误页误写入数据集。

参考

评论