news 2026/5/26 16:29:49

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/5/20 14:27:06

一、地理探测器:是什么?

Geo Detector是 用Excel编制的地理探测器软件, 可从以下网址免费下载:http://www.geodetector.org/。地理探测器方法简介地理探测器&#xff08;Geographical Detector&#xff09;是一种用于识别空间分异特征及其驱动因素的统计分析方法&#xff0c;最早由王劲峰等学者提出&am…

作者头像 李华
网站建设 2026/5/24 3:25:56

Python 爬虫实战:aiohttp 实现异步高并发爬虫

前言 传统同步爬虫受限于 “请求 - 等待 - 响应” 的串行执行模式&#xff0c;在面对海量 URL 采集场景时&#xff0c;I/O 等待时间占比极高&#xff0c;采集效率难以满足业务需求。异步编程通过事件循环机制&#xff0c;可在单个线程内同时处理多个网络请求&#xff0c;最大化…

作者头像 李华
网站建设 2026/5/20 23:14:07

Python 爬虫实战:asyncio 异步爬虫任务调度

前言 在基于 aiohttp 实现的异步爬虫中&#xff0c;单纯依靠 asyncio.gather 批量执行协程虽能实现高并发&#xff0c;但面对复杂场景&#xff08;如任务优先级调度、动态任务添加、任务失败重试、资源限流&#xff09;时&#xff0c;缺乏灵活的任务调度能力。asyncio 作为 Py…

作者头像 李华
网站建设 2026/5/24 19:58:42

必学收藏|AI Agent架构全解析:从ReAct到LangGraph设计模式

本文全面介绍了AI Agent的五大架构类型(反应型、审议式、混合、神经符号和认知)及LangGraph中的三大设计模式(多Agent系统、规划Agent、反思批判)。详细阐述了各架构特点、应用场景和优缺点&#xff0c;从基础到高级展示了AI Agent构建方法&#xff0c;强调选择合适架构的重要性…

作者头像 李华
网站建设 2026/5/22 8:48:50

COMSOL各向异性黑磷

comsol各向异性黑磷。搞黑磷模拟的朋友应该都懂&#xff0c;这玩意儿在不同方向上导电性能差异大到离谱。上次有个哥们拿着实验数据找我&#xff0c;说在COMSOL里死活复现不出黑磷的电流分布&#xff0c;我一看他的模型设置——好家伙&#xff0c;材料属性直接用了各向同性导电…

作者头像 李华