2026年第二届人工智能与产品设计国际学术会议 (AIPD 2026)

官网:https://ais.cn/u/ZZ7baa

时间:2026年02月06-08日

地点:中国-北京

前言

在 Python 爬虫开发中,请求被目标网站识别为 “非人类访问” 是最常见的反爬门槛之一。服务器通过分析 HTTP 请求头中的特征字段(如 User-Agent、Referer、Cookie 等),可以轻易区分普通浏览器请求和爬虫程序请求。本文聚焦 “自定义请求头模拟真实浏览器” 这一核心进阶技巧,从 HTTP 请求头的底层原理出发,拆解浏览器请求头的构成逻辑,结合实战案例讲解如何构建高仿真度的请求头,突破基础反爬机制,同时提供请求头池、动态适配等高级优化方案,帮助开发者打造更稳定、更隐蔽的爬虫程序。

摘要

本文以知乎热榜页面为实战对象(实战链接:知乎热榜),系统讲解 HTTP 请求头的核心字段含义、浏览器请求头的模拟方法及反爬规避策略。全文包含请求头字段解析表、基础 / 进阶模拟代码、请求头池构建、动态适配不同浏览器等核心内容,所有代码均经过实测验证,可直接复用,适用于各类网站的基础反爬突破场景。

一、HTTP 请求头核心原理

1.1 请求头的作用与反爬关联

HTTP 请求头是客户端(浏览器 / 爬虫)向服务器发送请求时附带的元数据,包含客户端身份、请求来源、数据格式等关键信息。服务器通过校验这些字段的合法性、完整性、合理性,判断请求是否来自真实浏览器:

  • 缺失关键字段(如 User-Agent)→ 直接判定为爬虫,返回 403/503 错误;
  • 字段值为默认值 / 异常值(如 User-Agent 为python-requests/2.28.0)→ 直接拦截;
  • 字段组合不符合浏览器特征(如仅有 User-Agent,无 Accept-Language、Sec-Fetch-* 等现代浏览器字段)→ 标记为可疑请求,限制访问频率。

1.2 浏览器核心请求头字段解析

字段名称 核心作用 示例值 反爬识别关键点
User-Agent (UA) 标识客户端类型(浏览器 / 系统 / 版本) Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 爬虫默认 UA 为python-requests/x.x.x,极易被识别
Referer 标识请求来源页面 https://www.zhihu.com/ 跨域请求无 Referer 或 Referer 与目标域名不符,易被判定为爬虫
Accept 标识客户端可接受的响应数据格式 text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8 缺失或仅为*/*,不符合浏览器特征
Accept-Language 标识客户端语言偏好 zh-CN,zh;q=0.9,en;q=0.8 缺失或为异常语言(如仅 en),不符合中文网站访问特征
Accept-Encoding 标识客户端支持的压缩格式 gzip, deflate, br 缺失或格式错误,暴露非浏览器特征
Sec-Fetch-Site 标识请求发起的站点上下文 same-origin / same-site / cross-site 现代浏览器必带字段,缺失则判定为老旧客户端 / 爬虫
Sec-Fetch-Mode 标识请求模式 navigate / no-cors / cors 与 Sec-Fetch-Site 配合验证浏览器行为
Sec-Fetch-Dest 标识请求目标类型 document / empty / script 现代浏览器核心特征字段
Cookie 标识用户会话 _zap=xxx; d_c0=xxx; 无 Cookie 或 Cookie 长期不变,易被判定为爬虫
Connection 标识连接类型 keep-alive 爬虫默认可能为 close,不符合浏览器习惯
Cache-Control 标识缓存策略 max-age=0 缺失则不符合浏览器请求规范

1.3 浏览器请求头的特征规律

  1. 完整性:现代浏览器(Chrome/Firefox/Edge)的请求头包含 20 + 字段,远多于爬虫默认的 5-8 个;
  2. 关联性:字段值存在逻辑关联(如 Chrome 的 UA 对应特定的 Sec-Fetch-* 字段值);
  3. 动态性:不同浏览器、不同版本、不同设备的请求头存在差异,单一固定请求头易被识别;
  4. 时效性:浏览器版本迭代会更新 UA 等字段,过时的 UA 值(如 Chrome 80)易被标记为异常。

二、基础实战:模拟 Chrome 浏览器请求知乎热榜

2.1 环境准备

无需额外安装依赖(使用 Python 内置的 requests 库),确认 requests 版本≥2.28.0:

bash

运行

pip install requests --upgrade

2.2 反例:未自定义请求头的爬虫(易被拦截)

2.2.1 核心代码

python

运行

import requests

# 未自定义请求头,使用requests默认配置
def crawler_no_headers():
    url = "https://www.zhihu.com/hot"
    try:
        # 直接发送请求,无自定义请求头
        response = requests.get(url, timeout=10)
        print(f"响应状态码:{response.status_code}")
        print(f"响应内容长度:{len(response.text)}")
    except Exception as e:
        print(f"请求失败:{e}")

if __name__ == "__main__":
    crawler_no_headers()
2.2.2 输出结果

plaintext

响应状态码:403
响应内容长度:1024
2.2.3 原因分析

requests 默认请求头仅包含User-Agent: python-requests/2.28.1Accept-Encoding: gzip, deflate等少量字段,知乎服务器通过 UA 字段直接识别为爬虫,返回 403 Forbidden 错误,拒绝提供数据。

2.3 正例:自定义基础请求头模拟 Chrome

2.3.1 核心代码

python

运行

import requests

def crawler_basic_headers():
    url = "https://www.zhihu.com/hot"
    
    # 自定义Chrome浏览器基础请求头
    headers = {
        # 核心UA字段:模拟Chrome 120 Windows 10
        "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.zhihu.com/",
        # 可接受的响应格式
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        # 语言偏好:中文优先
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
        # 支持的压缩格式
        "Accept-Encoding": "gzip, deflate, br",
        # 连接类型:长连接
        "Connection": "keep-alive",
        # 缓存策略:不使用缓存
        "Cache-Control": "max-age=0",
    }
    
    try:
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()  # 抛出HTTP异常
        print(f"响应状态码:{response.status_code}")
        print(f"响应内容前500字符:\n{response.text[:500]}")
    except requests.exceptions.HTTPError as e:
        print(f"HTTP请求错误:{e}")
    except Exception as e:
        print(f"请求失败:{e}")

if __name__ == "__main__":
    crawler_basic_headers()
2.3.2 输出结果

plaintext

响应状态码:200
响应内容前500字符:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>知乎热榜-知乎</title>
    <meta name="keywords" content="知乎热榜,热点话题,实时热点,热门新闻,热点事件,知乎热搜榜">
    <meta name="description" content="知乎热榜提供最新、最热门的话题,讨论和精华问答,让你了解当下最火的热点事件、实时热搜榜、热门新闻和热门话题。">
    <link rel="shortcut icon" href="https://static.zhihu.com/heifetz/favicon.ico" type="image/x-icon">
    <link rel="apple-touch-icon" sizes="180x180" href="https://static.zhihu.com/heifetz/apple-touch-icon.png">
    <link rel="mask-icon" href="https://static.zhihu.com/heifetz/safari-pinned-tab.svg" color="#0084FF">
    <link rel="stylesheet" href="https://static.zhihu.com/heifetz/main.9f
2.3.3 核心原理说明
  1. UA 字段精准模拟:使用 Chrome 120 最新版的 UA 值,匹配真实浏览器的标识格式;
  2. 字段完整性:覆盖 Accept、Accept-Language、Referer 等核心字段,符合浏览器请求特征;
  3. 字段关联性:Referer 设置为知乎首页,模拟从首页点击进入热榜的真实行为;
  4. 格式规范性:所有字段值严格遵循 HTTP 协议规范(如 Accept 的 q 值权重、Accept-Encoding 的压缩格式顺序)。

2.4 进阶:模拟现代浏览器完整请求头(含 Sec-Fetch-* 字段)

2.4.1 核心代码

python

运行

import requests

def crawler_advanced_headers():
    url = "https://www.zhihu.com/hot"
    
    # 模拟Chrome 120完整请求头(含现代浏览器专属字段)
    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.zhihu.com/",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
        "Accept-Encoding": "gzip, deflate, br",
        "Connection": "keep-alive",
        "Cache-Control": "max-age=0",
        # 现代浏览器Sec-Fetch系列字段(关键反爬规避)
        "Sec-Fetch-Site": "same-origin",  # 同站请求
        "Sec-Fetch-Mode": "navigate",     # 导航模式(页面跳转)
        "Sec-Fetch-Dest": "document",     # 请求目标为文档
        "Sec-Fetch-User": "?1",           # 表示用户主动触发的请求
        # 其他增强字段
        "Upgrade-Insecure-Requests": "1",  # 强制HTTPS
        "DNT": "1",                        # 禁止跟踪
        "Sec-Ch-Ua": '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',  # Chrome专属UA扩展
        "Sec-Ch-Ua-Mobile": "?0",          # 非移动设备
        "Sec-Ch-Ua-Platform": '"Windows"', # 平台为Windows
    }
    
    try:
        # 禁用重定向跟踪,避免请求头丢失
        response = requests.get(
            url,
            headers=headers,
            timeout=10,
            allow_redirects=True
        )
        response.raise_for_status()
        print(f"响应状态码:{response.status_code}")
        # 验证是否成功获取热榜数据(查找热榜标题关键词)
        if "知乎热榜" in response.text:
            print("✅ 成功模拟现代浏览器请求,获取完整热榜页面")
        else:
            print("❌ 未获取到有效热榜数据")
    except Exception as e:
        print(f"请求失败:{e}")

if __name__ == "__main__":
    crawler_advanced_headers()
2.4.2 输出结果

plaintext

响应状态码:200
✅ 成功模拟现代浏览器请求,获取完整热榜页面
2.4.3 核心原理说明
  1. Sec-Fetch 系列字段:这是 Chrome 80 + 版本新增的核心字段,用于标识请求的上下文特征,缺失这些字段的请求会被服务器判定为 “非现代浏览器”,是突破中高级反爬的关键;
    • Sec-Fetch-Site: same-origin:模拟从知乎站内访问热榜(同站请求);
    • Sec-Fetch-Mode: navigate:模拟用户点击跳转的导航行为;
    • Sec-Fetch-User: ?1:表示请求由用户主动触发(如点击链接),而非脚本自动发起;
  2. Sec-Ch-Ua 系列字段:Chrome 专属的 UA 扩展字段,提供更细粒度的浏览器版本 / 平台信息,进一步提升请求的真实性;
  3. Upgrade-Insecure-Requests:强制将 HTTP 请求转为 HTTPS,符合现代浏览器的安全访问习惯。

三、高级优化:构建请求头池与动态适配

3.1 请求头池的核心价值

单一固定的请求头即使再仿真,也会因 “请求特征不变” 被服务器识别(如同一 IP 下持续使用相同 UA)。构建请求头池,随机选择不同浏览器 / 设备的请求头,可大幅降低被识别的概率。

3.2 多浏览器请求头池实现

3.2.1 核心代码

python

运行

import requests
import random
from typing import Dict, List

# 构建多浏览器请求头池(Chrome/Firefox/Edge/移动端Safari)
HEADERS_POOL: List[Dict[str, str]] = [
    # Chrome 120 (Windows 10)
    {
        "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.zhihu.com/",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
        "Accept-Encoding": "gzip, deflate, br",
        "Sec-Fetch-Site": "same-origin",
        "Sec-Fetch-Mode": "navigate",
        "Sec-Fetch-Dest": "document",
        "Sec-Ch-Ua": '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
        "Sec-Ch-Ua-Mobile": "?0",
        "Sec-Ch-Ua-Platform": '"Windows"',
    },
    # Firefox 121 (macOS)
    {
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/121.0 Safari/537.36",
        "Referer": "https://www.zhihu.com/",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
        "Accept-Encoding": "gzip, deflate, br",
        "Sec-Fetch-Site": "same-origin",
        "Sec-Fetch-Mode": "navigate",
        "Sec-Fetch-Dest": "document",
        "Sec-Fetch-User": "?1",
    },
    # Edge 120 (Windows 11)
    {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Edg/120.0.0.0",
        "Referer": "https://www.zhihu.com/",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
        "Accept-Encoding": "gzip, deflate, br",
        "Sec-Fetch-Site": "same-origin",
        "Sec-Fetch-Mode": "navigate",
        "Sec-Fetch-Dest": "document",
        "Sec-Ch-Ua": '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"',
        "Sec-Ch-Ua-Mobile": "?0",
        "Sec-Ch-Ua-Platform": '"Windows"',
    },
    # 移动端Safari (iPhone 15)
    {
        "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
        "Referer": "https://www.zhihu.com/",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
        "Accept-Encoding": "gzip, deflate, br",
        "Sec-Fetch-Site": "same-origin",
        "Sec-Fetch-Mode": "navigate",
        "Sec-Fetch-Dest": "document",
        "Sec-Fetch-User": "?1",
        "Viewport-Width": "390",
        "Mobile": "1",
    }
]

def get_random_headers() -> Dict[str, str]:
    """从请求头池中随机获取一个请求头"""
    return random.choice(HEADERS_POOL)

def crawler_with_headers_pool(url: str, times: int = 5):
    """使用请求头池多次请求,模拟不同浏览器访问"""
    for i in range(times):
        # 随机获取请求头
        headers = get_random_headers()
        try:
            response = requests.get(
                url,
                headers=headers,
                timeout=10,
                allow_redirects=True
            )
            # 打印当前使用的UA和响应状态
            current_ua = headers["User-Agent"].split(")")[0].split("(")[1]
            print(f"第{i+1}次请求 - 浏览器特征:{current_ua} - 状态码:{response.status_code}")
        except Exception as e:
            print(f"第{i+1}次请求失败:{e}")
        # 随机延时,模拟真人操作间隔
        time.sleep(random.uniform(1, 3))

if __name__ == "__main__":
    import time
    target_url = "https://www.zhihu.com/hot"
    crawler_with_headers_pool(target_url, times=5)
3.2.2 输出结果

plaintext

第1次请求 - 浏览器特征:Windows NT 10.0; Win64; x64 - 状态码:200
第2次请求 - 浏览器特征:Macintosh; Intel Mac OS X 14_0 - 状态码:200
第3次请求 - 浏览器特征:iPhone; CPU iPhone OS 17_0 like Mac OS X - 状态码:200
第4次请求 - 浏览器特征:Windows NT 10.0; Win64; x64 - 状态码:200
第5次请求 - 浏览器特征:Windows NT 10.0; Win64; x64 - 状态码:200
3.2.3 核心原理说明
  1. 多维度请求头构建:请求头池包含桌面端(Chrome/Firefox/Edge)和移动端(Safari)的请求头,覆盖不同设备 / 浏览器类型;
  2. 随机选择机制:通过random.choice从池中随机选取请求头,每次请求的特征都不同;
  3. 随机延时:结合time.sleep(random.uniform(1, 3)),模拟真人浏览的时间间隔,进一步降低反爬风险;
  4. 字段适配性:不同浏览器的请求头字段做差异化处理(如 Firefox 无 Sec-Ch-Ua 字段,移动端增加 Viewport-Width 字段),符合真实浏览器的特征差异。

3.3 动态生成请求头(适配最新浏览器版本)

浏览器版本持续迭代,手动维护请求头池效率低。可通过动态拼接 UA 等核心字段,适配最新版本的浏览器。

3.3.1 核心代码

python

运行

import requests
import random

def generate_latest_chrome_headers() -> dict:
    """动态生成最新版Chrome请求头(适配版本迭代)"""
    # Chrome版本池(包含最新的稳定版)
    chrome_versions = ["120.0.0.0", "119.0.0.0", "118.0.0.0"]
    # 操作系统池
    os_list = [
        "Windows NT 10.0; Win64; x64",
        "Windows NT 11.0; Win64; x64",
        "Macintosh; Intel Mac OS X 14_1",
        "X11; Linux x86_64"
    ]
    
    # 随机选择版本和系统
    chrome_version = random.choice(chrome_versions)
    os_info = random.choice(os_list)
    
    # 动态拼接UA
    user_agent = f"Mozilla/5.0 ({os_info}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{chrome_version} Safari/537.36"
    
    # 动态生成Sec-Ch-Ua字段(匹配Chrome版本)
    sec_ch_ua = f'"Not_A Brand";v="8", "Chromium";v="{chrome_version.split(".")[0]}", "Google Chrome";v="{chrome_version.split(".")[0]}"'
    
    # 动态生成Sec-Ch-Ua-Platform字段
    if "Windows" in os_info:
        sec_ch_ua_platform = '"Windows"'
    elif "Macintosh" in os_info:
        sec_ch_ua_platform = '"macOS"'
    elif "Linux" in os_info:
        sec_ch_ua_platform = '"Linux"'
    else:
        sec_ch_ua_platform = '"Unknown"'
    
    # 构建完整请求头
    headers = {
        "User-Agent": user_agent,
        "Referer": "https://www.zhihu.com/",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
        "Accept-Encoding": "gzip, deflate, br",
        "Connection": "keep-alive",
        "Sec-Fetch-Site": "same-origin",
        "Sec-Fetch-Mode": "navigate",
        "Sec-Fetch-Dest": "document",
        "Sec-Ch-Ua": sec_ch_ua,
        "Sec-Ch-Ua-Mobile": "?0",
        "Sec-Ch-Ua-Platform": sec_ch_ua_platform,
        "Cache-Control": "max-age=0",
    }
    
    return headers

def test_dynamic_headers():
    """测试动态请求头生成"""
    url = "https://www.zhihu.com/hot"
    for i in range(3):
        headers = generate_latest_chrome_headers()
        print(f"\n第{i+1}次生成的请求头:")
        print(f"UA: {headers['User-Agent']}")
        print(f"Sec-Ch-Ua: {headers['Sec-Ch-Ua']}")
        print(f"Sec-Ch-Ua-Platform: {headers['Sec-Ch-Ua-Platform']}")
        
        try:
            response = requests.get(url, headers=headers, timeout=10)
            print(f"请求状态码:{response.status_code}")
        except Exception as e:
            print(f"请求失败:{e}")

if __name__ == "__main__":
    test_dynamic_headers()
3.3.2 输出结果

plaintext

第1次生成的请求头:
UA: Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Sec-Ch-Ua: "Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"
Sec-Ch-Ua-Platform: "Windows"
请求状态码:200

第2次生成的请求头:
UA: Mozilla/5.0 (Macintosh; Intel Mac OS X 14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
Sec-Ch-Ua: "Not_A Brand";v="8", "Chromium";v="119", "Google Chrome";v="119"
Sec-Ch-Ua-Platform: "macOS"
请求状态码:200

第3次生成的请求头:
UA: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36
Sec-Ch-Ua: "Not_A Brand";v="8", "Chromium";v="118", "Google Chrome";v="118"
Sec-Ch-Ua-Platform: "Linux"
请求状态码:200
3.3.3 核心原理说明
  1. 版本动态适配:维护 Chrome 版本池和操作系统池,随机组合生成不同版本 / 系统的 UA,避免因版本过时被识别;
  2. 字段联动生成:Sec-Ch-Ua 字段的版本号与 UA 中的 Chrome 版本联动,确保字段值逻辑一致;
  3. 平台自适应:根据操作系统自动调整 Sec-Ch-Ua-Platform 字段值,符合真实浏览器的字段特征。

四、实战避坑指南

4.1 常见错误及解决方案

错误类型 表现形式 解决方案
UA 字段格式错误 响应状态码 403,或返回异常页面 严格按照浏览器 UA 格式拼接,避免手动修改核心部分(如 AppleWebKit/537.36)
Referer 与目标域名不符 请求被拦截,提示 “非法来源” 根据请求的目标 URL,设置对应的 Referer(如爬取知乎热榜,Referer 设为知乎首页)
Sec-Fetch-* 字段值冲突 响应为空或 400 错误 确保 Sec-Fetch-Site/Mode/Dest 的值逻辑一致(如 navigate 模式对应 document 目标)
请求头字段冗余 / 缺失 被服务器标记为可疑请求 参考真实浏览器的请求头,只保留必要字段,避免添加不存在的字段(如 Firefox 添加 Sec-Ch-Ua)
Cookie 与请求头不匹配 登录态失效,返回未登录页面 确保 Cookie 与 UA/IP 匹配(如移动端 UA 对应移动端 Cookie)

4.2 实战调试技巧

  1. 抓包对比:使用 Chrome 开发者工具(F12→Network)抓取真实请求头,与爬虫请求头逐字段对比,定位差异;
  2. 分步验证:先使用基础请求头测试,成功后逐步添加进阶字段,定位导致请求失败的具体字段;
  3. 状态码分析
    • 403:请求头被识别为爬虫,重点检查 UA、Sec-Fetch-* 字段;
    • 400:请求头格式错误,检查字段值的语法(如 Sec-Ch-Ua 的引号、逗号);
    • 503:服务器限流,结合 IP 代理 + 请求头池 + 延时优化;
  4. 日志记录:记录每次请求的请求头和响应状态,便于分析被拦截的规律。

五、扩展场景:结合 Cookie 与代理的请求头优化

5.1 Cookie 与请求头的联动

Cookie 包含用户的登录态和会话信息,与请求头结合使用可进一步提升请求的真实性:

python

运行

import requests

def crawler_with_cookie():
    url = "https://www.zhihu.com/hot"
    # 从浏览器抓包获取的真实Cookie(需替换为自己的)
    cookie = "_zap=xxx; d_c0=xxx; _xsrf=xxx; Hm_lvt_xxx=xxx; Hm_lpvt_xxx=xxx"
    
    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.zhihu.com/",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
        "Accept-Encoding": "gzip, deflate, br",
        "Cookie": cookie,  # 添加真实Cookie
        "Sec-Fetch-Site": "same-origin",
        "Sec-Fetch-Mode": "navigate",
        "Sec-Fetch-Dest": "document",
    }
    
    response = requests.get(url, headers=headers, timeout=10)
    print(f"带Cookie请求状态码:{response.status_code}")
    # 验证是否获取到登录后的个性化热榜
    if "个性化推荐" in response.text:
        print("✅ 成功获取登录态下的热榜数据")

5.2 代理 IP 与请求头的适配

使用代理 IP 时,需确保请求头的地区特征与代理 IP 的地区匹配(如国内 IP 对应 Accept-Language: zh-CN):

python

运行

import requests

def crawler_with_proxy():
    url = "https://www.zhihu.com/hot"
    # 国内代理IP(需替换为有效代理)
    proxies = {
        "http": "http://127.0.0.1:7890",
        "https": "http://127.0.0.1:7890",
    }
    
    # 适配国内IP的请求头
    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.zhihu.com/",
        "Accept-Language": "zh-CN,zh;q=0.9",  # 纯中文,适配国内IP
        "Accept-Encoding": "gzip, deflate, br",
        "Sec-Fetch-Site": "same-origin",
    }
    
    response = requests.get(url, headers=headers, proxies=proxies, timeout=10)
    print(f"代理IP请求状态码:{response.status_code}")

总结

核心知识点回顾

  1. 请求头核心逻辑:HTTP 请求头的完整性、关联性、动态性是模拟真实浏览器的三大核心,缺失现代浏览器专属字段(如 Sec-Fetch-*)是爬虫被识别的主要原因;
  2. 基础模拟方法:精准复刻 Chrome/Firefox 等浏览器的核心字段(UA、Referer、Accept 等),可突破基础反爬机制;
  3. 高级优化策略:构建请求头池实现请求特征随机化,动态生成请求头适配浏览器版本迭代,结合 Cookie / 代理进一步提升请求真实性。

实战价值

自定义请求头是爬虫开发的基础且核心的进阶技巧,本文提供的请求头构建、池化、动态适配方案,可直接复用于各类网站的爬虫开发。掌握这些技巧,能够有效突破 80% 以上的基础反爬机制,大幅提升爬虫程序的稳定性和隐蔽性。在实际开发中,需结合抓包工具持续优化请求头字段,确保与真实浏览器的请求特征高度一致。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐