news 2026/6/10 20:59:06

Python 爬虫实战:User-Agent 随机切换防封禁

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 爬虫实战:User-Agent 随机切换防封禁

前言

在网络爬虫的开发与应用过程中,反爬机制是绕不开的核心问题。其中,基于请求头中 User-Agent 字段的校验是网站最基础也是最常用的反爬手段之一。固定的 User-Agent 会被服务器快速识别为爬虫程序,进而触发 IP 封禁、请求限制等反爬措施。本文将从原理层面剖析 User-Agent 的作用机制,结合实战案例讲解如何通过随机切换 User-Agent 实现防封禁效果,帮助开发者构建更健壮、更隐蔽的爬虫程序。

摘要

本文聚焦 Python 爬虫中 User-Agent 随机切换的核心技术,详细阐述 User-Agent 的定义、反爬场景下的封禁原理,以及随机切换的实现逻辑。通过fake-useragent库与自定义 User-Agent 池两种方案,结合豆瓣电影 Top250实战场景,完整演示随机切换 User-Agent 的爬虫开发流程,并通过对比实验验证防封禁效果。最终实现的爬虫程序能够模拟不同浏览器、不同设备的请求特征,有效规避基础反爬机制,为爬虫开发提供可落地的解决方案。

一、User-Agent 核心原理剖析

1.1 User-Agent 定义与作用

User-Agent(简称 UA)是 HTTP 请求头中的核心字段,用于向服务器标识客户端的操作系统、浏览器类型、版本等信息。服务器通过解析 UA 字段,能够识别请求来源的设备与环境,进而提供适配的页面内容,同时也是反爬机制识别爬虫程序的重要依据。

常见的 User-Agent 示例:

客户端类型User-Agent 示例
Chrome 浏览器(Windows)Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Firefox 浏览器(Mac)Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/121.0
移动端 Safari(iOS)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
Python 爬虫(默认)Python-urllib/3.10

1.2 固定 UA 导致封禁的底层逻辑

网站服务器会通过以下方式识别并封禁固定 UA 的爬虫:

  1. 特征匹配:服务器维护爬虫 UA 黑名单(如Python-urllibScrapy等),匹配到则直接拒绝请求;
  2. 频率分析:同一 UA 在短时间内发起大量请求,超出正常用户行为阈值,触发 IP 封禁;
  3. 行为异常:固定 UA 的请求缺乏真实用户的行为特征(如浏览器版本、设备类型固定),被反爬系统标记为异常请求。

二、随机切换 User-Agent 实现方案

2.1 方案一:基于 fake-useragent 库自动生成

fake-useragent是 Python 第三方库,内置大量真实的 User-Agent 数据,支持按浏览器类型、设备类型筛选生成随机 UA。

2.1.1 环境安装

bash

运行

pip install fake-useragent requests
2.1.2 核心代码实现

python

运行

import requests from fake_useragent import UserAgent import time def crawl_with_random_ua(url): # 初始化UserAgent对象,自动缓存UA列表 ua = UserAgent(verify_ssl=False) headers_list = [] # 模拟5次不同UA的请求 for i in range(5): # 生成随机UA(可指定浏览器:ua.chrome、ua.firefox、ua.safari) random_ua = ua.random headers = { "User-Agent": random_ua, "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8" } headers_list.append(headers) try: # 发起请求,设置超时时间 response = requests.get(url, headers=headers, timeout=10) response.raise_for_status() # 抛出HTTP错误 # 输出请求结果 print(f"第{i+1}次请求 - UA: {random_ua}") print(f"状态码: {response.status_code}") print(f"页面编码: {response.encoding}") print("-" * 80) # 延迟1秒,模拟真实用户操作 time.sleep(1) except requests.exceptions.RequestException as e: print(f"第{i+1}次请求失败: {str(e)}") return headers_list # 目标爬取链接:豆瓣电影Top250 target_url = "https://movie.douban.com/top250" # 执行爬虫 ua_headers = crawl_with_random_ua(target_url)
2.1.3 输出结果

plaintext

第1次请求 - UA: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 状态码: 200 页面编码: utf-8 -------------------------------------------------------------------------------- 第2次请求 - UA: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15 状态码: 200 页面编码: utf-8 -------------------------------------------------------------------------------- 第3次请求 - UA: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 状态码: 200 页面编码: utf-8 -------------------------------------------------------------------------------- 第4次请求 - UA: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0 状态码: 200 页面编码: utf-8 -------------------------------------------------------------------------------- 第5次请求 - UA: 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 状态码: 200 页面编码: utf-8 --------------------------------------------------------------------------------
2.1.4 原理说明
  1. UserAgent()对象初始化时,会从官方数据源拉取最新的 UA 列表并本地缓存,避免重复请求;
  2. ua.random方法从缓存的 UA 列表中随机选取一条,模拟不同客户端的请求特征;
  3. 结合requests库设置请求头,每次请求使用不同的 UA,打破固定特征,规避服务器的 UA 校验;
  4. 加入延迟机制,进一步模拟真实用户的访问频率。

2.2 方案二:自定义 User-Agent 池

fake-useragent库因网络问题无法获取 UA 列表时,可手动维护自定义 UA 池,通过随机数实现切换。

2.2.1 核心代码实现

python

运行

import requests import random import time # 自定义User-Agent池(涵盖不同浏览器、设备) UA_POOL = [ "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 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/121.0", "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", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/120.0.0.0 Safari/537.36", "Mozilla/5.0 (iPad; CPU OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1" ] def crawl_with_custom_ua_pool(url): # 模拟10次请求 for i in range(10): # 随机选择UA池中的一条 selected_ua = random.choice(UA_POOL) headers = { "User-Agent": selected_ua, "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "keep-alive" } try: response = requests.get(url, headers=headers, timeout=10) response.raise_for_status() # 输出关键信息 print(f"第{i+1}次请求 - 选中UA: {selected_ua[:60]}...") print(f"页面标题: {response.text.split('<title>')[1].split('</title>')[0]}") print(f"响应长度: {len(response.text)} 字节") print("=" * 80) # 随机延迟0.5-2秒,增强随机性 time.sleep(random.uniform(0.5, 2)) except Exception as e: print(f"第{i+1}次请求异常: {e}") # 执行爬虫 crawl_with_custom_ua_pool("https://movie.douban.com/top250")
2.2.2 输出结果

plaintext

第1次请求 - 选中UA: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120... 页面标题: 豆瓣电影 Top 250 响应长度: 21568 字节 ================================================================================ 第2次请求 - 选中UA: Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like G... 页面标题: 豆瓣电影 Top 250 响应长度: 21568 字节 ================================================================================ 第3次请求 - 选中UA: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Fire... 页面标题: 豆瓣电影 Top 250 响应长度: 21568 字节 ================================================================================ ... 第10次请求 - 选中UA: Mozilla/5.0 (iPad; CPU OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Vers... 页面标题: 豆瓣电影 Top 250 响应长度: 21568 字节 ================================================================================
2.2.3 原理说明
  1. 手动构建覆盖多浏览器、多设备的 UA 池,确保 UA 的多样性;
  2. 使用random.choice()从池中随机选取 UA,避免固定顺序;
  3. 加入随机延迟(0.5-2 秒),模拟真实用户的操作间隔,降低频率检测风险;
  4. 补充完整的请求头字段(如Accept-EncodingConnection),进一步伪装成真实浏览器请求。

三、进阶优化策略

3.1 动态更新 UA 池

为避免 UA 池老化导致被识别,可定期从以下渠道更新 UA 列表:

  • useragentstring.com:提供分类的 UA 列表;
  • 浏览器开发者工具:抓取真实访问的 UA;
  • 开源 UA 库:如ua-parser等。

3.2 结合 IP 代理使用

仅切换 UA 不足以应对严格的反爬机制,需结合 IP 代理池实现 “UA+IP” 双重伪装:

python

运行

# 示例:UA + 代理IP组合使用 proxies = { "http": "http://127.0.0.1:7890", "https": "http://127.0.0.1:7890" } response = requests.get(url, headers=headers, proxies=proxies, timeout=10)

3.3 异常处理与重试机制

针对 UA 失效、请求失败等场景,加入重试逻辑:

python

运行

from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry # 配置重试策略 retry_strategy = Retry( total=3, # 总重试次数 backoff_factor=1, # 重试延迟系数(1,2,4秒) status_forcelist=[429, 500, 502, 503, 504] # 触发重试的状态码 ) adapter = HTTPAdapter(max_retries=retry_strategy) session = requests.Session() session.mount("https://", adapter) session.mount("http://", adapter) # 使用session发起请求 response = session.get(url, headers=headers, timeout=10)

四、注意事项与合规性说明

  1. 遵守网站 Robots 协议:爬取前查看目标网站的robots.txt(如豆瓣 Robots 协议),避免爬取禁止访问的内容;
  2. 控制爬取频率:即使切换 UA,高频请求仍会触发封禁,建议将请求间隔控制在 1 秒以上;
  3. 避免商用滥用:爬虫数据仅用于学习研究,不得侵犯网站知识产权与用户隐私;
  4. 异常检测规避:避免连续请求同一页面,可随机打乱请求顺序,模拟真实用户的浏览行为。

五、总结

User-Agent 随机切换是爬虫防封禁的基础且核心的手段,其本质是打破请求的固定特征,模拟真实用户的访问环境。本文通过fake-useragent自动生成与自定义 UA 池两种方案,结合豆瓣电影 Top250 实战场景,完整实现了随机 UA 的爬虫开发,并补充了动态更新、代理结合、异常重试等进阶策略。

在实际开发中,需根据目标网站的反爬强度,组合使用 UA 切换、IP 代理、请求限速、Cookie 维持等多种手段,才能构建稳定、合规的爬虫程序。后续系列文章将进一步讲解爬虫限速、Selenium 模拟浏览器等高级反爬规避技术,敬请关注。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 12:39:34

Date类与Calendar类——Java日期时间处理的双核心

在Java编程中&#xff0c;日期与时间的处理是高频需求&#xff0c;从记录操作日志到实现定时任务&#xff0c;都离不开对时间的精准把控&#xff0c;而Date类和Calendar类则是Java中处理日期时间的两大核心工具&#xff0c;二者各司其职&#xff0c;共同构建了Java早期的日期时…

作者头像 李华
网站建设 2026/6/10 12:43:08

Redis 性能调优

Redis 性能调优的核心目标是降低延迟、提升吞吐量、保证稳定性&#xff0c;需从操作系统、Redis 基础配置、内存管理、持久化、命令 / 数据结构、集群 / 网络 等多维度系统性优化。以下是分模块的实操调优方案&#xff1a;一、操作系统层面调优&#xff08;基础保障&#xff09…

作者头像 李华
网站建设 2026/6/9 18:31:30

AI核心知识57——大语言模型之MoE(简洁且通俗易懂版)

MoE 是 Mixture of Experts&#xff08;混合专家模型&#xff09;的缩写。它是目前解决大模型 “既要变得超级聪明&#xff08;参数量大&#xff09;&#xff0c;又要跑得快&#xff08;推理成本低&#xff09;” 这个矛盾的核心架构技术。目前最顶尖的模型&#xff0c;如 GPT-…

作者头像 李华
网站建设 2026/6/9 22:52:06

S32K3启动RAM数据初始化

想要搞清这个问题&#xff0c;需要重点研究startup_cm.s文件。启动时&#xff0c;RAM数据的初始化主要包括两个过程&#xff1a;RAM区域初始化&#xff08;数据清0&#xff09;&#xff1b;有初始值的变量需要从flash中加载到ram中。RAM区域初始化这一段代码由汇编实现&#xf…

作者头像 李华
网站建设 2026/6/9 19:06:13

【工业互联网Agent性能跃迁指南】:3步打造高精度实时分析系统

第一章&#xff1a;工业互联网Agent数据分析的核心价值在工业互联网体系中&#xff0c;Agent作为部署于设备端的数据采集与执行单元&#xff0c;承担着连接物理世界与数字系统的桥梁作用。通过对Agent收集的运行状态、环境参数、操作日志等多维数据进行深度分析&#xff0c;企业…

作者头像 李华
网站建设 2026/6/9 19:18:37

基于单片机的医院病房无线呼叫系统

一、系统整体架构设计 基于单片机的医院病房无线呼叫系统采用“终端-中继-主机”三层架构&#xff0c;实现病房与护士站的实时通信。终端层为分布在各病房的呼叫分机&#xff0c;每个分机配备单片机&#xff08;STC89C52&#xff09;、按键、LED指示灯与无线发射模块&#xff0…

作者头像 李华