如何用Python+Selenium点击#shadow-root(closed)中的ReCAPTCHA按钮?
问题分析与解决方案
核心限制:Closed Shadow Root无法直接访问
#shadow-root(closed)是浏览器为安全设置的隔离机制,Selenium常规API根本没法直接获取里面的元素,这是你代码失效的主要原因。
你代码里的明显错误
- 用
By.CLASS_NAME定位button-holder help-button-holder是错误的,这个方法只能传单个类名,多个类名得用CSS选择器div.button-holder.help-button-holder - 代码里先找shadow_host,又重复从shadow_element取shadow_root,逻辑混乱
可行的解决办法
方法1:用JavaScript直接触发点击(绕过Shadow Root)
通过执行JS脚本直接定位并点击Buster按钮,不用管shadow root的限制。修改后的recaptcha函数示例:
def recaptcha(driver): wait = WebDriverWait(driver, 10) try: # 等待并切换到reCAPTCHA的iframe wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[src*='recaptcha']"))) # 用JS遍历找到Buster按钮并点击 driver.execute_script(""" const buttons = document.querySelectorAll('.button-holder button'); for(let btn of buttons) { if(btn.textContent.includes('Buster') || btn.title.includes('Buster')) { btn.click(); break; } } """) print("Buster按钮已触发") # 切回主页面 driver.switch_to.default_content() except NoSuchElementException as erro: print(f"错误: {erro}") print("未找到reCAPTCHA元素,跳过验证") except Exception as e: print(f"发生意外错误: {e}")
方法2:用Buster的快捷键触发
Buster扩展默认支持Alt+Shift+B快捷键启动验证,直接模拟按键即可,完全不用管shadow root:
from selenium.webdriver.common.keys import Keys def recaptcha(driver): wait = WebDriverWait(driver, 10) try: # 切换到reCAPTCHA的iframe wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[src*='recaptcha']"))) # 模拟按下Alt+Shift+B ActionChains(driver).key_down(Keys.ALT).key_down(Keys.SHIFT).send_keys('b').key_up(Keys.SHIFT).key_up(Keys.ALT).perform() print("已通过快捷键触发Buster") driver.switch_to.default_content() # 等待验证完成 sleep(15) except NoSuchElementException as erro: print(f"错误: {erro}") print("未找到reCAPTCHA元素,跳过验证") except Exception as e: print(f"发生意外错误: {e}")
方法3:确保扩展正确加载
在setup_driver里增加延迟,保证Buster扩展完全加载:
def setup_driver(): options = webdriver.FirefoxOptions() driver = webdriver.Firefox(options=options) extension_path = "/home/work04/.mozilla/firefox/vyrx65nr.default-release/extensions/{e58d3966-3d76-4cd9-8552-1582fbc800c1}.xpi" driver.install_addon(extension_path, temporary=True) driver.maximize_window() driver.implicitly_wait(10) # 等待扩展加载完成 sleep(5) return driver
内容的提问来源于stack exchange,提问作者Julia
相关产品推荐
相关产品推荐

