如何用Python Selenium点击按钮后获取Base64验证码图片
问题:Selenium无法获取加载完成的Base64验证码图片
我用Python Selenium尝试获取Base64格式的验证码图片,但始终只能拿到验证码加载前的HTML——不管是driver.page_source还是通过JS获取的innerHTML里,都只有"Loading"字样,找不到data:image/png;base64标识。
操作代码如下:
# load packages from selenium.webdriver import EdgeOptions from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.microsoft import EdgeChromiumDriverManager from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC options = EdgeOptions() options.add_argument("--headless") options.add_argument('disable-gpu') driver = webdriver.Edge(service=Service(EdgeChromiumDriverManager().install()), options=options) # access website driver.get("https://boards.4channel.org/o/") # open post driver.execute_script("document.getElementsByClassName('mobilePostFormToggle mobile hidden button')[0].click()") # click this ID driver.execute_script("document.getElementById('t-load').click()") # This will get the initial html - before javascript html1 = driver.page_source # This will get the html after on-load javascript html2 = driver.execute_script("return document.documentElement.innerHTML;") # check for base64 images 'Loading' in html1 # True 'Loading' in html2 # True # check for base64 images 'data:image/png;base64' in html1 # False 'data:image/png;base64' in html2 # False
触发验证码的按钮HTML:
<button id="t-load" type="button" data-board="o" data-tid="0" style="font-size: 11px; padding: 0px; width: 90px; box-sizing: border-box; margin: 0px 6px 0px 0px; vertical-align: middle; height: 18px;">Get Captcha</button>
解决方案
核心问题是未等待验证码异步加载完成,点击"Get Captcha"后页面需要请求验证码资源,直接获取HTML会拿到未加载完成的状态。按以下方式修改代码:
- 替换JS直接操作元素的方式,改用Selenium显式等待确保元素可交互后再点击
- 点击后,显式等待验证码的Base64内容加载完成
修改后的代码:
# 加载依赖包 from selenium.webdriver import EdgeOptions from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.microsoft import EdgeChromiumDriverManager from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC options = EdgeOptions() options.add_argument("--headless") options.add_argument('disable-gpu') # 无头模式添加窗口大小,避免元素渲染异常 options.add_argument("--window-size=1920,1080") driver = webdriver.Edge(service=Service(EdgeChromiumDriverManager().install()), options=options) # 访问目标页面 driver.get("https://boards.4channel.org/o/") # 显式等待发帖按钮加载完成并点击 post_btn = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.CLASS_NAME, "mobilePostFormToggle")) ) post_btn.click() # 显式等待获取验证码按钮加载完成并点击 captcha_btn = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, "t-load")) ) captcha_btn.click() # 等待验证码加载完成:两种方式二选一 # 方式1:等待页面中出现Base64图片标识 WebDriverWait(driver, 15).until( lambda d: 'data:image/png;base64' in d.page_source ) # 方式2:等待"Loading"文本消失(若验证码容器有固定选择器可替换为更精准的定位) # WebDriverWait(driver, 15).until( # EC.invisibility_of_element_located((By.XPATH, "//*[contains(text(), 'Loading')]")) # ) # 此时获取的页面源码已包含加载完成的验证码 final_html = driver.page_source # 验证结果 print('data:image/png;base64' in final_html) # 应为True driver.quit()
关键说明
- 避免用原生JS直接定位元素,Selenium的显式等待能更好适配页面动态加载逻辑
- 无头模式建议固定窗口大小,部分网站会根据窗口尺寸渲染不同布局
- 等待时长可根据网络状况调整,10-15秒足以应对大多数场景
内容的提问来源于stack exchange,提问作者John Stud
相关产品推荐
相关产品推荐

