
前言目标站点依靠请求头 UA 字段识别爬虫特征固定单一 User-Agent 高频请求极易触发访问限制、验证码拦截、IP 封禁。UA 池通过海量浏览器标识随机轮换搭配 Cookie、Referer、Accept 等请求头字段动态组装破除单一请求指纹特征结合移动端 / PC 端 UA 分类、权重随机分发、异常 UA 自动剔除从请求报文层面伪装成真实客户端访问。本章实现可复用 UA 池模块无缝对接前面单机爬虫、定时爬虫、分布式爬虫、代理 IP 池项目配套完整封装代码与反指纹优化方案。本文所需依赖官方文档超链接Requests 官方文档Random 内置库Redis-Py 官方文档一、UA 反爬原理与指纹风控逻辑1.1 UA 风控判定规则长期固定同一个 UA 高频请求服务器标记为爬虫特征UA 标识为爬虫引擎python-requests/xxx直接拦截请求头字段残缺无 Accept、Accept-Language报文指纹异常被拦截。1.2 请求头指纹组成要素对照表表格字段作用反爬影响User-Agent客户端浏览器标识核心风控字段爬虫首要伪装点Referer来源页面地址缺失易被判定直接恶意访问Accept可接收资源类型缺失导致请求头残缺指纹异常Accept-Language系统语言标识完善头部伪装真实浏览器1.3 UA 池设计思路分类存储 PC 端、移动端、平板三类 UA按需定向取用内置权重机制主流高版本浏览器 UA 分配更高随机概率支持 Redis 持久化 UA 池动态新增、淘汰失效 UA封装统一获取请求头函数一行代码获取完整 headers 字典。二、环境依赖bash运行pip install redis5.0.8 requests2.31.0三、基础本地 UA 静态池轻量化小型爬虫3.1 UA 数据源分类封装python运行import random # PC端Chrome、Edge、Firefox高版本UA PC_UA_LIST [ Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36, Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.2420.97, Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0, Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36, ] # 移动端安卓、IOS UA MOBILE_UA_LIST [ Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15, Mozilla/5.0 (Linux; Android 14; SM-G998B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36, ] # 权重配置PC权重8移动端权重2 UA_WEIGHT_MAP { pc:8, mobile:2 }3.2 随机取 UA 自动组装完整请求头python运行def get_random_ua(ua_type:str auto) - str: ua_type: pc/mobile/auto auto按权重随机选择设备类型 if ua_type pc: return random.choice(PC_UA_LIST) elif ua_type mobile: return random.choice(MOBILE_UA_LIST) else: # 权重随机选型 total UA_WEIGHT_MAP[pc] UA_WEIGHT_MAP[mobile] rand_num random.randint(1,total) if rand_num UA_WEIGHT_MAP[pc]: return random.choice(PC_UA_LIST) else: return random.choice(MOBILE_UA_LIST) def get_random_headers(refer:str None, ua_type:strauto) - dict: 生成随机完整请求头 ua get_random_ua(ua_type) headers { User-Agent:ua, Accept:text/html,application/xhtmlxml,application/xml;q0.9,image/webp,*/*;q0.8, Accept-Language:zh-CN,zh;q0.9,en;q0.8, Accept-Encoding:gzip, deflate, br, Connection:keep-alive, Upgrade-Insecure-Requests:1 } if refer: headers[Referer] refer return headers3.3 爬虫调用示例python运行import requests def demo_crawl(url): headers get_random_headers(referurl) resp requests.get(url,headersheaders,timeout8) return resp.status_code if __name__ __main__: print(demo_crawl(https://httpbin.org/headers))四、Redis 分布式 UA 池适配分布式爬虫多节点爬虫共享 UA 资源支持动态新增 UA、标记失效 UA统一由 Redis 集合存储可用 UA。python运行import redis # redis初始化 REDIS_CFG {host:127.0.0.1,port:6379,db:0,decode_responses:True} rds redis.Redis(**REDIS_CFG) PC_UA_KEY ua:pool:pc MOBILE_UA_KEY ua:pool:mobile # 初始化导入默认UA仅首次运行执行 def init_ua_to_redis(): rds.sadd(PC_UA_KEY,*PC_UA_LIST) rds.sadd(MOBILE_UA_KEY,*MOBILE_UA_LIST) # 随机从Redis取UA def get_redis_ua(ua_typeauto): if ua_type pc: return rds.srandmember(PC_UA_KEY) elif ua_type mobile: return rds.srandmember(MOBILE_UA_KEY) else: # 权重随机 if random.randint(1,10) 8: return rds.srandmember(PC_UA_KEY) else: return rds.srandmember(MOBILE_UA_KEY) # 动态新增UA到池 def add_new_ua(ua_str:str,ua_typepc): if ua_type pc: rds.sadd(PC_UA_KEY,ua_str) else: rds.sadd(MOBILE_UA_KEY,ua_str) # 标记失效UA并移除 def remove_bad_ua(ua_str:str,ua_typepc): if ua_type pc: rds.srem(PC_UA_KEY,ua_str) else: rds.srem(MOBILE_UA_KEY,ua_str)五、高级反指纹优化请求头随机微调固定请求头字段顺序、固定参数内容会形成固定指纹对部分字段值做小范围随机。python运行def get_rand_finger_header(referNone): ua get_random_ua() # 随机Accept编码顺序 enc_list [gzip, deflate, br,gzip, deflate,br,gzip,deflate] rand_enc random.choice(enc_list) header { User-Agent:ua, Accept:text/html,application/xhtmlxml,application/xml;q0.9,image/webp,*/*;q0.8, Accept-Language:random.choice([zh-CN,zh;q0.9,zh-CN,zh;q0.8,en;q0.7]), Accept-Encoding:rand_enc, Connection:keep-alive, Upgrade-Insecure-Requests:1 } if refer: header[Referer] refer return header六、搭配代理 IP 池联合使用同时轮换 UA 代理 IP双重打散请求指纹大幅降低封禁概率python运行# 对接代理池接口 PROXY_API http://127.0.0.1:5010/get_proxy FAIL_PROXY_API http://127.0.0.1:5010/proxy_fail/ def crawl_proxy_ua(target_url): # 获取随机代理 proxy_res requests.get(PROXY_API).json() if proxy_res[code] !200: return None proxy proxy_res[proxy] proxies {http:fhttp://{proxy},https:fhttp://{proxy}} # 随机请求头 headers get_rand_finger_header(refertarget_url) try: res requests.get(target_url,headersheaders,proxiesproxies,timeout7) return res.text except Exception: requests.get(f{FAIL_PROXY_API}{proxy}) return None七、定时扩充 UA 数据源APScheduler 自动更新 UA 池python运行from apscheduler.schedulers.background import BackgroundScheduler def auto_add_ua(): 模拟定时从UA数据源接口拉取新UA入库Redis new_pc_ua [Mozilla/5.0 (Windows NT 11.0; Win64; x64) Chrome/125.0.0.0 Safari/537.36] for ua in new_pc_ua: add_new_ua(ua,pc) print(新增UA完成) def start_ua_update_task(): sch BackgroundScheduler() sch.add_job(auto_add_ua,interval,hours6,idua_auto_update) sch.start() if __name__ __main__: start_ua_update_task()八、常见问题与优化表表格异常现象优化方案部分 UA 请求直接 403调用 remove_bad_ua 剔除失效 UA补充新版本浏览器 UA仍被站点识别爬虫增加 Cookie 随机池、间隔随机 sleep (0.5~2)分布式多节点 UA 重复率高统一接入 Redis UA 池全局共用数据源请求头固定特征启用字段随机微调函数打乱 Accept、Accept-Language 参数