
本文介绍如何使用 selenium 的 `screenshot_as_png` 属性直接截取 captcha `` 元素的渲染图像(而非重新请求 url),从而确保获取页面当前显示的、唯一的验证码图片,适用于 ocr 识别场景。
在自动化登录或表单提交过程中,CAPTCHA 图像通常通过动态生成的 URL(如 https://rds3.northsouth.edu/index.php/captcha)提供,每次 HTTP 请求都会返回一个全新、不可复现的验证码。因此,直接 GET 该 URL 获取的图像,与页面中实际展示的 CAPTCHA 完全不同——这正是你遇到问题的根本原因。
正确做法是:跳过网络请求,直接捕获浏览器已渲染的 元素像素内容。Selenium WebDriver 提供了 screenshot_as_png(Python)或 getScreenshotAs(OutputType.FILE)(Java)等原生能力,可对任意 WebElement 进行局部截图,且该截图反映的是 DOM 当前状态下的真实渲染结果,完全规避了服务端动态生成带来的不一致性。
以下是完整、可运行的 Python 实现流程(基于 Selenium 4+、OpenCV、pytesseract):
from selenium import webdriver
from selenium.webdriver.common.by import By
import cv2
import numpy as np
import pytesseract
import matplotlib.image as mpimg
# 初始化驱动(以 Chrome 为例)
driver = webdriver.Chrome()
driver.get("https://rds3.northsouth.edu/login") # 替换为实际登录页URL
# 定位 CAPTCHA 图片元素(根据实际 ID 或 XPath 调整)
captcha_img = driver.find_element(By.ID, "captcha-img") # 或 By.XPATH: '//img[@id="captcha-img"]'
# ✅ 关键步骤:直接截取该 img 元素的渲染图像(字节流)
png_bytes = captcha_img.screenshot_as_png
# 保存为本地文件(可选,便于调试)
with open("captcha.png", "wb") as f:
f.write(png_bytes)
# 使用 OpenCV 加载并预处理图像(注意:screenshot_as_png 返回 BGR 格式 PNG)
nparr = np.frombuffer(png_bytes, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
# 灰度化 → 放大 → 二值化(增强 OCR 可读性)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
h, w = gray.shape
resized = cv2.resize(gray, (w * 2, h * 2))
_, binary = cv2.threshold(resized, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# OCR 识别(确保已安装 tesseract-ocr 并配置环境变量)
captcha_text = pytesseract.image_to_string(binary, config='--psm 8 -c tessedit_char_whitelist=0123456789abcdefghijklmnopqrstuvwxyz').strip()
print("识别结果:", captcha_text)
# 填入表单(示例)
driver.find_element(By.ID, "captcha-input").send_keys(captcha_text)✅ 核心优势说明:
- screenshot_as_png 是浏览器端渲染快照,不受服务端随机种子/Session 绑定影响;
- 无需额外 HTTP 请求,避免触发反爬机制或消耗无效验证码配额;
- 支持任意复杂样式(如叠加噪点、扭曲、透明背景),只要视觉上可辨即可处理。
⚠️ 注意事项:
- 确保 CAPTCHA
元素在视口内(可调用 captcha_img.location_once_scrolled_into_view);
- 若页面使用 Canvas 渲染 CAPTCHA,则 screenshot_as_png 仍有效,但需确认 Canvas 是否被跨域策略阻断(通常静态资源无此问题);
- pytesseract 识别效果高度依赖图像质量,建议结合 cv2.morphologyEx、自适应阈值等进一步优化预处理流程;
- 生产环境请添加异常处理(如元素未找到、OCR 为空、超时重试等)。
总结:永远不要通过重复请求 CAPTCHA URL 来获取图像——它天生就是“一次性的”。唯一可靠的方式,是抓取浏览器此刻正在显示的那个 元素的渲染帧。 这一原则同样适用于其他动态内容(如实时图表、水印文本等)。










