使用 Selenium 采集视频平台数据时频繁遇到验证码,这是一个非常普遍且棘手的问题。这表明该平台部署了成熟的行为风控系统(如阿里云的“风险识别”服务、腾讯云的“天御”等),能够有效检测自动化脚本。
核心结论:单纯依赖 Selenium 很难彻底解决此问题,需要多维度对抗风控。
以下是系统性的解决方案和应对策略:
一、 根本原因分析
验证码的触发通常基于以下行为特征:
浏览器指纹异常:Selenium 启动的浏览器有明显的
webdriver特征。操作行为不自然:鼠标移动轨迹、点击间隔、页面停留时间过于规律。
网络环境可疑:IP 频繁更换、来自数据中心(非住宅IP)。
请求频率过高:短时间内大量请求,不符合人类行为。
缺少用户交互:无滚动、无鼠标悬停、无键盘输入。
二、 综合解决方案(由易到难)
方案1:伪装 Selenium 浏览器指纹(基础必备)
目标是让浏览器看起来像一个真实的用户浏览器。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
# 1. 隐藏 webdriver 特征
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
# 2. 设置真实 User-Agent
options.add_argument("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")
# 3. 禁用自动化标志
options.add_argument("--disable-infobars")
options.add_argument("--disable-extensions")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
driver = webdriver.Chrome(options=options)
# 4. 执行 JS 覆盖 navigator.webdriver
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => false
});
"""
})
# 5. 设置窗口大小(避免最小化)
driver.set_window_size(1366, 768)注意:仅做这些可能还不够,但这是第一步。
方案2:模拟人类操作行为
让操作更“人性化”,避免机械式点击。
import time
import random
from selenium.webdriver.common.action_chains import ActionChains
def human_click(driver, element):
"""模拟人类点击:带延迟、随机偏移"""
action = ActionChains(driver)
# 随机等待
time.sleep(random.uniform(1, 3))
# 移动到元素附近,再精确点击(模拟手抖)
action.move_to_element_with_offset(element,
random.randint(-10, 10),
random.randint(-10, 10))
action.pause(random.uniform(0.5, 1.5))
action.click()
action.perform()
def human_scroll(driver):
"""模拟人类滚动:分段滚动,随机停顿"""
total_height = driver.execute_script("return document.body.scrollHeight")
viewport_height = driver.execute_script("return window.innerHeight")
current = 0
while current < total_height:
scroll_by = random.randint(100, 300)
current += scroll_by
driver.execute_script(f"window.scrollTo(0, {current});")
time.sleep(random.uniform(0.5, 1.5))方案3:使用代理 IP 池
避免因 IP 请求过多被封禁。
选择优质代理:
使用住宅代理(Residential Proxy)而非数据中心代理,IP 更真实。
推荐服务商:Luminati(现 Bright Data)、Oxylabs、Smartproxy。
轮换 IP:
options.add_argument('--proxy-server=http://ip:port')在每次启动浏览器或每N次请求后更换 IP。
方案4:结合 OCR 或打码平台(处理验证码本身)
如果无法完全规避验证码,就直接解决它。
OCR 识别:
简单的数字/字母验证码可用
pytesseract+ 图像预处理。复杂验证码效果差。
第三方打码平台:
# 示例:调用打码平台API def solve_captcha(image_path): # 上传图片,获取文字结果 result = captch_solver.solve(image_path) return result
如:超级鹰、若快打码、云打码。
成本低(几分钱/次),准确率高。
方案5:升级为 Puppeteer + Playwright
Selenium 容易被检测,可尝试更新的技术栈。
Playwright:
更现代,支持多语言(Python/JS/Java/.NET)。
提供更好的隐身模式和设备模拟。
可模拟移动端。
Puppeteer (Node.js):
Google 官方维护,与 Chrome 集成度高。
社区插件丰富,如
puppeteer-extra+stealth-plugin可自动隐藏大部分自动化特征。
方案6:逆向工程 + 直接 API 调用(推荐,但需技术)
最高效、最稳定的方法:绕过前端,直接调用平台的真实 API。
F12 打开开发者工具 → Network 标签。
在网页上进行操作(如翻页、搜索),观察发起了哪些
XHR或Fetch请求。找到返回 JSON 数据的接口(如
/api/v1/videos/list)。分析其请求参数、Headers(尤其是
User-Agent,Referer,Cookie,X-Requested-With)、加密逻辑(如有)。使用
requests库直接调用 API,效率远高于 Selenium。
import requests
headers = {
'User-Agent': '真实浏览器UA',
'Referer': 'https://xxx.com/',
'Cookie': 'your_cookie_here'
}
params = {
'page': 1,
'size': 20,
# 其他必要参数
}
response = requests.get('https://api.xxx.com/v1/videos',
headers=headers, params=params)
data = response.json()优点:速度快、资源消耗低、不易触发前端风控。缺点:API 可能有签名、加密、Token 过期等反爬机制,需要深入分析。
三、 终极建议
| 场景 | 推荐方案 |
|---|---|
| 少量数据,临时采集 | Selenium + 代理 + 行为模拟 + 打码平台 |
| 中等规模,长期采集 | 直接调用 API + 动态 Cookie/Token 维护 + 代理池 |
| 大规模商业采集 | 专业爬虫框架(Scrapy)+ 分布式 + 自研反反爬模块 |
四、 法律与道德提醒
遵守
robots.txt和网站《用户协议》。避免对目标服务器造成过大压力(控制请求频率)。
不采集敏感或受版权保护的数据。
总结:解决 Selenium 验证码问题不能只靠单一方法。最佳实践是:使用 Playwright/Puppeteer 隐藏指纹 + 模拟人类行为 + 优质代理 IP + 直接调用后端 API。如果只是简单需求,可以接受打码平台的成本。