Selenium自动化与手动浏览时网站表现不一致:验证码页面无反馈问题
嘿,我碰到过不少这类网站反爬导致的自动化异常,咱们来聊聊你遇到的这个问题!
首先,你描述的现象——用Selenium打开验证码页面后,不管手动输入正确还是错误的验证码都没反馈、甚至白屏,而正常手动浏览就没问题——大概率是网站的反自动化检测机制在起作用,或者是Selenium会话的环境和真实浏览器差异太大导致的,具体原因可能有这几个:
1. Selenium的特征被网站识别了
即使你加了自定义的user-agent,Selenium还是有很多独特的“指纹”会被网站检测到:比如navigator.webdriver属性会返回true、浏览器窗口的特征、JS执行的轨迹和真实用户不一样。网站一旦识别出这是自动化工具,可能会返回不完整的页面资源,或者直接拦截后续的验证码提交请求,导致你输入后没任何反应。
2. 页面加载不完整就开始操作
你切换到新窗口后直接用sleep(1000)等待,但这种固定等待不一定能保证页面的所有JS资源都加载完成。如果验证码提交的逻辑依赖的JS还没加载好,就算你手动输入了内容,点击提交也触发不了后续的请求,自然就没反馈。
3. 会话/Cookie缺失
手动浏览时,你的浏览器可能已经保存了该网站的会话Cookie(比如之前访问留下的痕迹),而Selenium每次启动都是全新的会话,缺少这些Cookie的话,网站可能会认为你的请求不合法,拒绝处理验证码提交。
解决办法试试这些:
(1)隐藏Selenium的自动化特征
给ChromeOptions添加更多反检测配置,尽量让Selenium的环境接近真实浏览器:
options = Options() options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36") # 禁用自动化控制提示 options.add_argument("--disable-blink-features=AutomationControlled") # 移除自动化扩展和开关 options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option('useAutomationExtension', False) driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) # 注入脚本修改webdriver属性 driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) """ })
(2)用显式等待替代固定sleep
切换窗口后,等待验证码相关的元素加载完成,确保页面逻辑就绪:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def move_to_voting_page(driver, URL): driver.get(URL) input_element = driver.find_element(By.XPATH, "//input[@value='Vote for Asteria MU SEASON 20 PART 1-2 - 99999x']") input_element.click() # 等待新窗口出现 WebDriverWait(driver, 10).until(lambda d: len(d.window_handles) > 1) driver.switch_to.window(driver.window_handles[-1]) # 等待验证码输入框加载完成(替换成实际的选择器) WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "input[name='captcha']")) ) return driver
(3)导入真实浏览器的Cookie
手动打开目标网站,登录或正常访问后,导出浏览器的Cookie,然后在Selenium会话中添加这些Cookie,模拟真实用户的会话:
# 先打开网站的主页,确保域名匹配 driver.get("https://www.xtremetop100.com") # 把你从手动浏览器复制的Cookie添加进去,格式是[{"name": "cookie_name", "value": "cookie_value", "domain": ".xtremetop100.com"}] cookies = [ # 替换成你实际导出的Cookie {"name": "example_cookie", "value": "example_value", "domain": ".xtremetop100.com"} ] for cookie in cookies: driver.add_cookie(cookie) # 刷新页面后再进行后续操作 driver.refresh()
(4)检查验证码是否在iframe中
有些网站会把验证码放在iframe里,如果是这种情况,你需要先切换到iframe才能操作输入框:
# 切换到验证码所在的iframe(替换成实际的iframe选择器) iframe = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, "//iframe[contains(@src, 'captcha')]")) ) driver.switch_to.frame(iframe) # 这里操作验证码输入框 # 操作完成后切回主文档 driver.switch_to.default_content()
总的来说,这类问题核心就是网站不想被自动化工具薅羊毛,所以做了各种检测。你需要尽量让Selenium的行为和环境贴近真实用户,才能绕过这些限制。
备注:内容来源于stack exchange,提问作者Vardan Verma

