news 2026/5/26 7:25:50

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/26 5:56:10

Python 爬虫实战:爬虫代理 IP 池搭建与自动切换

摘要 本文聚焦爬虫代理 IP 池的核心搭建与自动切换技术&#xff0c;针对反爬机制中 IP 封禁的核心痛点&#xff0c;系统讲解代理 IP 池的架构设计、数据源对接、有效性检测、自动切换及动态维护全流程。实战验证基于IP 检测测试页&#xff08;可直接点击验证 IP 有效性&#x…

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

JAVA面相对象编程—抽象类、接口

#JAVA笔记#抽象类定义抽象类与普通类基本类似&#xff0c;唯一的区别在于使用abstract关键字修饰&#xff0c;且类中有未实现&#xff08;没有方法体&#xff09;的抽象方法&#xff08;abstract修饰&#xff09;。抽象方法必须位于抽象类中&#xff0c;抽象方法只能访问抽象成…

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

2026最新网络安全小白自学之路,别到处拜师了!!

较为完整的学习路线&#xff1a; 这个路线是我和一些已入职大佬来规划整理&#xff0c;也加上了小提示&#xff0c;我也希望你们能看看上面我的心得&#xff0c;都会有所帮助。 第一阶段&#xff0c;初入门学网络基础tip&#xff1a;这部分没有什么逻辑可以说的&#xff0c;半个…

作者头像 李华
网站建设 2026/5/25 8:35:02

加入2025护网,日薪最低1500,能力越强薪资越高!

加入2025护网&#xff0c;日薪最低1500&#xff0c;能力越强薪资越高&#xff01; 什么是护网行动 ** ** 1.护网行动 护网&#xff0c;也称网络保护&#xff0c;是指网络安全人员对企业或组织的网络进行检查、维护和保护&#xff0c;以防止网络受到黑客攻击、病毒、木马或其…

作者头像 李华
网站建设 2026/5/24 17:24:41

Selenium切换窗口、框架和弹出框window、ifame、alert

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、切换窗口#获取打开的多个窗口句柄 windows driver.window_handles #切换到当前最新打开的窗口 driver.switch_to.window(windows[-1]) #最大化浏览器 driv…

作者头像 李华
网站建设 2026/5/26 7:22:03

一个人,一家独角兽公司:代码的终结与创造者的崛起

刚看完 Silicon Valley Girl 采访 Replit CEO Amjad Masad 的视频&#xff0c;后劲很大。Amjad 在视频里抛出了一个非常炸裂的预测&#xff1a;“我们很快就会看到第一家由单人创办并运营的 10 亿美元估值&#xff08;Unicorn&#xff09;公司。”注意&#xff0c;是一人公司&a…

作者头像 李华