Python爬虫零基础入门【第三章:Requests 静态爬取入门·第2节】伪装与会话:Headers、Session、Cookie(合规使用)!

🔥本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~持续更新中!!

全文目录:

      • [🌟 开篇语](#🌟 开篇语)
      • [📌 上期回顾](#📌 上期回顾)
      • [🎯 本节目标](#🎯 本节目标)
      • [一、HTTP 请求头详解](#一、HTTP 请求头详解)
        • [1.1 为什么需要设置请求头?](#1.1 为什么需要设置请求头?)
        • [1.2 常用请求头字段详解](#1.2 常用请求头字段详解)
        • [1.3 真实浏览器的请求头](#1.3 真实浏览器的请求头)
      • 二、User-Agent:第一道防线
        • [2.1 常见的 User-Agent](#2.1 常见的 User-Agent)
        • [2.2 随机 User-Agent(避免特征识别)](#2.2 随机 User-Agent(避免特征识别))
        • [2.3 从浏览器复制 User-Agent](#2.3 从浏览器复制 User-Agent)
      • 三、Session:管理会话状态
        • [3.1 为什么需要 Session?](#3.1 为什么需要 Session?)
        • [3.2 Session 基本用法](#3.2 Session 基本用法)
        • [3.3 Session 封装类(推荐)](#3.3 Session 封装类(推荐))
      • 四、处理需要登录的网站(合规方式)
        • [4.1 合规声明](#4.1 合规声明)
        • [4.2 方法1:手动登录后复制 Cookie](#4.2 方法1:手动登录后复制 Cookie)
        • [4.3 方法2:通过表单登录(适用于简单网站)](#4.3 方法2:通过表单登录(适用于简单网站))
        • [4.4 验证登录状态](#4.4 验证登录状态)
      • 五、常见反爬机制与应对
        • [5.1 User-Agent 检测](#5.1 User-Agent 检测)
        • [5.2 Referer 检测](#5.2 Referer 检测)
        • [5.3 请求频率限制](#5.3 请求频率限制)
        • [5.4 Cookie/Session 验证](#5.4 Cookie/Session 验证)
      • 六、本节小结
      • 七、课后作业(必做,验收进入下一节)
        • [任务1:完善 SmartSession](#任务1:完善 SmartSession)
        • [任务2:测试 Session 的 Cookie 持久化](#任务2:测试 Session 的 Cookie 持久化)
        • 任务3:实战练习
      • [🔮 下期预告](#🔮 下期预告)
      • 🌟文末
        • [📌 专栏持续更新中|建议收藏 + 订阅](#📌 专栏持续更新中|建议收藏 + 订阅)
        • [✅ 互动征集](#✅ 互动征集)

🌟 开篇语

哈喽,各位小伙伴们你们好呀~我是【喵手】。

运营社区: C站 / 掘金 / 腾讯云 / 阿里云 / 华为云 / 51CTO

欢迎大家常来逛逛,一起学习,一起进步~🌟

我长期专注 Python 爬虫工程化实战 ,主理专栏 👉 《Python爬虫实战》:从采集策略反爬对抗 ,从数据清洗分布式调度 ,持续输出可复用的方法论与可落地案例。内容主打一个"能跑、能用、能扩展 ",让数据价值真正做到------抓得到、洗得净、用得上

📌 专栏食用指南(建议收藏)

  • ✅ 入门基础:环境搭建 / 请求与解析 / 数据落库
  • ✅ 进阶提升:登录鉴权 / 动态渲染 / 反爬对抗
  • ✅ 工程实战:异步并发 / 分布式调度 / 监控与容错
  • ✅ 项目落地:数据治理 / 可视化分析 / 场景化应用

📣 专栏推广时间 :如果你想系统学爬虫,而不是碎片化东拼西凑,欢迎订阅/关注专栏《Python爬虫实战》

订阅后更新会优先推送,按目录学习更高效~

📌 上期回顾

在上一节《你的第一个爬虫:抓取页面并保存 HTML》中,我们编写了第一个爬虫,成功抓取并保存了网页 HTML。你已经掌握了 requests 的基本用法和文件保存规范。

但现实中,很多网站会检测访问者的身份。如果请求过于"简陋",服务器会认为你是机器人而拒绝访问。这一节,我们将学习如何合理地伪装请求,让爬虫更像真实用户。

重要提醒:本节教授的是合规的请求优化技术,不涉及破解、盗号等违法行为!

🎯 本节目标

通过本节学习,你将能够:

  1. 理解 HTTP 请求头的作用和常用字段
  2. 设置完整的 User-Agent、Referer 等请求头
  3. 使用 Session 对象管理会话和 Cookie
  4. 处理需要登录的场景(合规方式)
  5. 识别和避免常见的反爬机制
  6. 交付验收:编写 Session 版请求器,支持 Cookie 持久化

一、HTTP 请求头详解

1.1 为什么需要设置请求头?

默认请求的问题

python 复制代码
import requests

# ❌ 最简单的请求
response = requests.get("https://example.com/")

# 实际发送的请求头(非常简陋)
"""
GET / HTTP/1.1
Host: example.com
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
"""

服务器视角

  • 看到 User-Agent: python-requests/2.31.0 → 这是爬虫!
  • 缺少 Referer → 不是从网站内部跳转来的
  • 缺少浏览器特有的请求头 → 可疑!

结果:很多网站会直接返回 403 Forbidden 或空白页面。

1.2 常用请求头字段详解
字段 作用 示例值
User-Agent 标识客户端类型 Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Referer 来源页面URL https://example.com/list
Accept 可接受的内容类型 text/html,application/json
Accept-Language 可接受的语言 zh-CN,zh;q=0.9,en;q=0.8
Accept-Encoding 支持的编码 gzip, deflate, br
Cookie 会话凭证 session_id=abc123; token=xyz
Host 目标主机 www.example.com
Connection 连接方式 keep-alive
1.3 真实浏览器的请求头
python 复制代码
# ✅ 模拟 Chrome 浏览器的完整请求头
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',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,'
              'image/webp,image/apng,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
    'Accept-Encoding': 'gzip, deflate, br',
    'Referer': 'https://www.google.com/',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'cross-site',
    'Cache-Control': 'max-age=0'
}

response = requests.get(url, headers=headers)

二、User-Agent:第一道防线

2.1 常见的 User-Agent
python 复制代码
# Windows Chrome
UA_CHROME_WIN = (
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
    '(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
)

# Mac Safari
UA_SAFARI_MAC = (
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 '
    '(KHTML, like Gecko) Version/17.2 Safari/605.1.15'
)

# iPhone Safari
UA_IPHONE = (
    'Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 '
    '(KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1'
)

# Android Chrome
UA_ANDROID = (
    'Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 '
    '(KHTML, like Gecko) Chrome/120.0.6099.144 Mobile Safari/537.36'
)
2.2 随机 User-Agent(避免特征识别)
python 复制代码
import random

class UserAgentPool:
    """User-Agent 池"""
    
    AGENTS = [
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15',
    ]
    
    @classmethod
    def random(cls):
        """返回随机 User-Agent"""
        return random.choice(cls.AGENTS)

# 使用
headers = {'User-Agent': UserAgentPool.random()}
response = requests.get(url, headers=headers)
2.3 从浏览器复制 User-Agent

步骤

  1. 打开浏览器开发者工具(F12)
  2. 切换到 Network 标签
  3. 刷新页面,点击任意请求
  4. 在 Headers 部分找到 User-Agent
  5. 复制完整字符串
python 复制代码
# 从浏览器复制的真实 User-Agent
MY_USER_AGENT = "粘贴你从浏览器复制的内容"

三、Session:管理会话状态

3.1 为什么需要 Session?

问题场景

python 复制代码
# ❌ 每次请求都是独立的,Cookie 不会保留
response1 = requests.get("https://example.com/login", data={...})
response2 = requests.get("https://example.com/profile")  # 失败!未登录

# 原因:response1 返回的 Cookie 没有在 response2 中携带

Session 的作用

  • ✅ 自动保存和发送 Cookie
  • ✅ 跨请求保持连接(性能更好)
  • ✅ 统一管理请求头
3.2 Session 基本用法
python 复制代码
import requests

# 创建 Session 对象
session = requests.Session()

# 设置统一的请求头
session.headers.update({
    'User-Agent': UserAgentPool.random(),
    'Accept-Language': 'zh-CN,zh;q=0.9',
})

# 第一次请求
response1 = session.get("https://httpbin.org/cookies/set?session_id=abc123")
print("Set-Cookie:", response1.headers.get('Set-Cookie'))

# 第二次请求(自动携带上次的 Cookie)
response2 = session.get("https://httpbin.org/cookies")
print("发送的 Cookie:", response2.json())
# 输出:{"cookies": {"session_id": "abc123"}}
3.3 Session 封装类(推荐)
python 复制代码
import requests
import time
import json
import os

class SmartSession:
    """智能 Session 管理器"""
    
    def __init__(self, cookie_file=None):
        """
        初始化
        
        Args:
            cookie_file: Cookie 持久化文件路径
        """
        self.session = requests.Session()
        self.cookie_file = cookie_file
        
        # 设置默认请求头
        self.session.headers.update({
            'User-Agent': UserAgentPool.random(),
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Accept-Encoding': 'gzip, deflate',
            'Connection': 'keep-alive',
        })
        
        # 加载已保存的 Cookie
        if cookie_file and os.path.exists(cookie_file):
            self.load_cookies()
    
    def get(self, url, **kwargs):
        """GET 请求(带重试)"""
        return self._request('GET', url, **kwargs)
    
    def post(self, url, **kwargs):
        """POST 请求(带重试)"""
        return self._request('POST', url, **kwargs)
    
    def _request(self, method, url, max_retries=3, retry_delay=2, **kwargs):
        """
        发起请求(内部方法)
        
        Args:
            method: 请求方法
            url: 目标URL
            max_retries: 最大重试次数
            retry_delay: 重试延迟(秒)
            **kwargs: 传递给 requests 的参数
        """
        for attempt in range(max_retries):
            try:
                if method == 'GET':
                    response = self.session.get(url, timeout=10, **kwargs)
                else:
                    response = self.session.post(url, timeout=10, **kwargs)
                
                response.raise_for_status()
                return response
                
            except requests.exceptions.RequestException as e:
                print(f"❌ 请求失败 (尝试 {attempt+1}/{max_retries}): {e}")
                
                if attempt < max_retries - 1:
                    time.sleep(retry_delay)
                else:
                    raise
    
    def save_cookies(self):
        """保存 Cookie 到文件"""
        if not self.cookie_file:
            return
        
        # 将 Cookie 转为字典
        cookies_dict = requests.utils.dict_from_cookiejar(self.session.cookies)
        
        with open(self.cookie_file, 'w') as f:
            json.dump(cookies_dict, f, indent=2)
        
        print(f"💾 Cookie 已保存到: {self.cookie_file}")
    
    def load_cookies(self):
        """从文件加载 Cookie"""
        if not os.path.exists(self.cookie_file):
            return
        
        with open(self.cookie_file, 'r') as f:
            cookies_dict = json.load(f)
        
        # 将字典转为 Cookie
        for name, value in cookies_dict.items():
            self.session.cookies.set(name, value)
        
        print(f"📂 Cookie 已加载: {self.cookie_file}")
    
    def set_cookie(self, name, value, domain=None):
        """手动设置 Cookie"""
        self.session.cookies.set(name, value, domain=domain)
    
    def get_cookies(self):
        """获取当前所有 Cookie"""
        return requests.utils.dict_from_cookiejar(self.session.cookies)
    
    def close(self):
        """关闭 Session"""
        self.session.close()

# ========== 使用示例 ==========

# 示例1:基本用法
session = SmartSession()
response = session.get("https://httpbin.org/get")
print(response.json())

# 示例2:Cookie 持久化
session = SmartSession(cookie_file='cookies.json')

# 第一次访问(会设置 Cookie)
response1 = session.get("https://httpbin.org/cookies/set?token=abc123")

# 保存 Cookie
session.save_cookies()

# ===== 重启程序 =====

# 加载之前保存的 Cookie
session2 = SmartSession(cookie_file='cookies.json')
response2 = session2.get("https://httpbin.org/cookies")
print("恢复的 Cookie:", response2.json())

四、处理需要登录的网站(合规方式)

4.1 合规声明

⚠️ 重要:本节只教授合规的登录方式:

  • ✅ 使用自己的账号登录
  • ✅ 采集自己有权限访问的数据
  • 禁止破解他人账号
  • 禁止绕过付费墙
  • 禁止访问未授权数据

步骤

  1. 用浏览器正常登录网站
  2. 打开开发者工具(F12)→ Application/存储
  3. 找到 Cookies,复制所有 Cookie
  4. 在代码中手动设置
python 复制代码
session = SmartSession()

# 手动设置从浏览器复制的 Cookie
cookies = {
    'session_id': 'abc123def456',
    'user_token': 'xyz789',
    'user_id': '12345',
}

for name, value in cookies.items():
    session.set_cookie(name, value)

# 现在可以访问需要登录的页面
response = session.get("https://example.com/profile")
4.3 方法2:通过表单登录(适用于简单网站)
python 复制代码
def login(session, login_url, username, password):
    """
    表单登录
    
    Args:
        session: SmartSession 对象
        login_url: 登录接口URL
        username: 用户名
        password: 密码
    
    Returns:
        bool: 是否登录成功
    """
    # 登录表单数据
    data = {
        'username': username,
        'password': password,
        # 'csrf_token': '...',  # 如果需要CSRF令牌
    }
    
    try:
        response = session.post(login_url, data=data)
        
        # 检查登录是否成功(根据实际情况调整)
        if '登录成功' in response.text or response.status_code == 200:
            print("✅ 登录成功")
            
            # 保存 Cookie 以便下次使用
            session.save_cookies()
            return True
        else:
            print("❌ 登录失败")
            return False
            
    except Exception as e:
        print(f"❌ 登录异常: {e}")
        return False

# 使用示例
session = SmartSession(cookie_file='login_cookies.json')

# 首次登录
if not os.path.exists('login_cookies.json'):
    login(session, 
          login_url="https://example.com/login",
          username="your_username",
          password="your_password")

# 后续使用已保存的 Cookie
response = session.get("https://example.com/data")
4.4 验证登录状态
python 复制代码
def check_login_status(session, check_url):
    """
    检查是否已登录
    
    Args:
        session: SmartSession 对象
        check_url: 检查登录状态的URL(如个人主页)
    
    Returns:
        bool: 是否已登录
    """
    try:
        response = session.get(check_url)
        
        # 根据响应内容判断(需根据实际网站调整)
        if '退出登录' in response.text or '个人中心' in response.text:
            print("✅ 已登录")
            return True
        else:
            print("❌ 未登录或登录已过期")
            return False
            
    except Exception as e:
        print(f"❌ 检查失败: {e}")
        return False

五、常见反爬机制与应对

5.1 User-Agent 检测

检测方式:服务器检查 User-Agent 是否为常见爬虫

应对

python 复制代码
# ✅ 使用随机 User-Agent
headers = {'User-Agent': UserAgentPool.random()}
5.2 Referer 检测

检测方式:检查请求是否来自站内跳转

应对

python 复制代码
# 示例:访问详情页时,设置 Referer 为列表页
headers = {
    'Referer': 'https://example.com/news/list'
}
response = session.get('https://example.com/news/detail/123', headers=headers)
5.3 请求频率限制

检测方式:同一 IP 短时间内请求过多

应对

python 复制代码
import time

urls = [...]

for url in urls:
    response = session.get(url)
    # 处理数据...
    
    # 延迟 2-5 秒(礼貌爬取)
    time.sleep(random.uniform(2, 5))
5.4 Cookie/Session 验证

检测方式:检查 Cookie 是否存在或有效

应对

python 复制代码
# 使用 Session 自动管理 Cookie
session = SmartSession(cookie_file='cookies.json')

六、本节小结

本节我们学习了请求伪装的核心技能:

请求头设置 :User-Agent、Referer、Accept 等字段

Session 管理 :自动保存和发送 Cookie

Cookie 持久化 :保存到文件,下次自动加载

登录处理 :合规的登录方式和状态检查

反爬应对:识别常见机制并合理应对

核心原则

  • 模拟真实浏览器,但不伪造身份
  • 使用自己的账号,不访问未授权数据
  • 控制请求频率,礼貌爬取
  • Cookie 敏感信息要妥善保管

七、课后作业(必做,验收进入下一节)

任务1:完善 SmartSession

SmartSession 类添加以下方法:

python 复制代码
def set_proxy(self, proxy_url):
    """设置代理(如有需要)"""
    pass

def clear_cookies(self):
    """清除所有 Cookie"""
    pass

def export_cookies_to_browser_format(self, output_file):
    """导出为浏览器可导入的格式(Netscape format)"""
    pass

编写脚本:

  1. 访问 httpbin.org/cookies/set 设置 Cookie
  2. 保存 Cookie 到文件
  3. 重新创建 Session 并加载 Cookie
  4. 验证 Cookie 是否成功恢复
任务3:实战练习

选择一个需要简单登录的网站(建议用测试网站或自己的账号):

  1. 手动登录后复制 Cookie
  2. 在代码中设置 Cookie
  3. 访问需要登录才能看到的页面
  4. 验证是否成功获取数据

验收方式:在留言区提交:

  • 扩展功能的代码
  • Cookie 持久化测试的运行截图
  • 实战练习的结果(注意隐藏敏感信息)
  • 学习心得

🔮 下期预告

下一节《稳定性第一课:超时、重试、退避》,我们将学习:

  • 为什么超时设置是必需的
  • 实现智能重试机制(指数退避)
  • 区分哪些错误该重试,哪些不该
  • 失败日志的设计规范
  • 编写 HttpClient v1(生产级请求器)

预习建议

思考:当一个请求失败时,应该立即重试、还是等待一段时间?等待多久合适?


💬 Session 是稳定爬虫的基石!掌握它,事半功倍!

记住:伪装不是欺骗,而是让你的爬虫更"礼貌"。合规合法地采集数据,是工程师的职业操守。

🌟文末

好啦~以上就是本期 《Python爬虫实战》的全部内容啦!如果你在实践过程中遇到任何疑问,欢迎在评论区留言交流,我看到都会尽量回复~咱们下期见!

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦~
三连就是对我写作道路上最好的鼓励与支持! ❤️🔥

📌 专栏持续更新中|建议收藏 + 订阅

专栏 👉 《Python爬虫实战》,我会按照"入门 → 进阶 → 工程化 → 项目落地"的路线持续更新,争取让每一篇都做到:

✅ 讲得清楚(原理)|✅ 跑得起来(代码)|✅ 用得上(场景)|✅ 扛得住(工程化)

📣 想系统提升的小伙伴:强烈建议先订阅专栏,再按目录顺序学习,效率会高很多~

✅ 互动征集

想让我把【某站点/某反爬/某验证码/某分布式方案】写成专栏实战?

评论区留言告诉我你的需求,我会优先安排更新 ✅


⭐️ 若喜欢我,就请关注我叭~(更新不迷路)

⭐️ 若对你有用,就请点赞支持一下叭~(给我一点点动力)

⭐️ 若有疑问,就请评论留言告诉我叭~(我会补坑 & 更新迭代)


免责声明:本文仅用于学习与技术研究,请在合法合规、遵守站点规则与 Robots 协议的前提下使用相关技术。严禁将技术用于任何非法用途或侵害他人权益的行为。

相关推荐
小白学大数据3 小时前
绕过拼多多 App 反抓包机制的综合逆向解决方案
开发语言·爬虫·python·自动化
使者大牙3 小时前
【单点知识】 Python装饰器介绍
开发语言·数据库·python
Jackson@ML3 小时前
2026最新版Sublime Text 4安装使用指南
java·python·编辑器·sublime text
TonyLee0173 小时前
半监督学习介绍
人工智能·python·深度学习·机器学习
kong79069283 小时前
Python核心语法-Python自定义模块、Python包
开发语言·python·python核心语法
OLOLOadsd1233 小时前
基于Mask-RCNN和RegNetX的茎蛀虫检测识别系统详解
python
半路_出家ren3 小时前
1.古典密码概述
python·网络安全·密码学·古典密码·加密方式
CJenny4 小时前
Claude Code常用操作和使用方法
人工智能·python
事橙19994 小时前
KITTI数据集国内下载链接
人工智能·python·yolo