在自动化测试中,处理验证码通常是一个难题,尤其是在登录流程中。验证码图像每次刷新时都会发生变化,因此需要一种方式来自动化识别这些验证码。常见的处理方法有两种:
获取验证码图片 URL 并下载:抓取验证码的 URL 地址来直接下载图片。然而,由于验证码每次都会刷新,直接访问 URL 获取的验证码图像可能与页面上显示的不一致,因此不总是有效。
截图并裁剪验证码区域:通过截图获取整个页面的内容,然后定位验证码区域,裁剪并识别验证码图像内容。使用 OCR(光学字符识别)技术来提取验证码文本。
以下是使用 Nim 语言处理验证码的详细实现步骤。
解决方案
方法一:获取验证码图片 URL 并下载
nim
更多内容访问ttocr.com或联系1436423940
import httpclient, os, strutils, random
获取验证码图片 URL
proc getCaptchaUrl(driver: cstring): cstring =
let element = driver.findElementById("imgvercodeLogin")
let captchaUrl = element.getAttribute("src")
return captchaUrl & ".png"
下载验证码图片
proc saveImage(imgUrl: cstring, fileName: cstring, filePath: cstring) =
if not fileExists(filePath):
mkdir(filePath)
let filePathWithName = filePath & "/" & fileName & ".png"
let client = HttpClient()
client.download(imgUrl, filePathWithName)
echo "验证码图片保存成功:", filePathWithName
在这个实现中,我们首先从网页中获取验证码的 URL 地址,并拼接 .png 后缀。然后使用 HttpClient 下载图片并保存到指定路径。
方法二:截图并裁剪验证码区域
nim
import os, random, time, strutils
import nimx # 假设 nimx 是图像处理库,用于截图和裁剪图片
截图并裁剪验证码区域
proc cropCaptchaImage(driver: cstring, savePath: cstring, captchaElementId: cstring): cstring =
let screenshotName = &"screenshot_" & $random(100000, 999999) & ".png"
let screenshotPath = savePath & "/" & screenshotName
driver.takeScreenshot(screenshotPath) # 获取整个页面的截图
let captchaElement = driver.findElementById(captchaElementId)
let (captchaX, captchaY) = captchaElement.getLocation()
let (captchaWidth, captchaHeight) = captchaElement.getSize()
计算裁剪区域的坐标
let captchaRight = captchaX + captchaWidth
let captchaBottom = captchaY + captchaHeight
打开截图文件并裁剪验证码区域
let img = loadImage(screenshotPath)
let captchaImg = cropImage(img, captchaX, captchaY, captchaRight, captchaBottom)
let croppedImagePath = savePath & "/" & screenshotName & "_captcha.png"
saveImage(croppedImagePath, captchaImg) # 保存裁剪后的验证码图像
return croppedImagePath
在这段代码中,我们首先获取页面的完整截图,然后通过定位验证码元素,裁剪出验证码图像。最后,将裁剪后的验证码图像保存到本地。
获取并识别验证码
nim
import nimx, random
import ocr # 假设 ocr 是 Nim 中的 OCR 库
识别验证码中的文本
proc recognizeCaptchaText(imagePath: cstring): cstring =
let img = loadImage(imagePath)
let text = ocr.recognizeText(img) # 使用 OCR 库识别图像中的文本
echo "识别到的验证码:", text
return text
这里,我们使用了一个假设的 ocr 库,通过加载图像并使用 OCR 技术识别其中的文本,返回验证码内容。
自动填写验证码
nim
import os, time
自动截图、裁剪、识别并填写验证码
proc solveCaptchaAndLogin(driver: cstring, savePath: cstring, captchaElementId: cstring, captchaInputId: cstring) =
let captchaImagePath = cropCaptchaImage(driver, savePath, captchaElementId) # 截图并裁剪验证码
let captchaText = recognizeCaptchaText(captchaImagePath) # 识别验证码
let captchaInput = driver.findElementById(captchaInputId)
captchaInput.sendKeys(captchaText) # 将识别到的验证码输入到表单中
time.sleep(2) # 等待验证码输入完成
此函数通过调用之前的 cropCaptchaImage 和 recognizeCaptchaText 函数获取验证码图像,并识别其中的文本。然后,将识别到的验证码输入到相应的输入框中。
登录流程
nim
import time
启动浏览器并打开登录页面
let driver = startWebDriver("chrome")
driver.get("http://www.cncaq.com/")
填写用户名和密码
driver.findElementById("loginNameText").sendKeys("188XXXXXXXX")
driver.findElementById("passwordText").sendKeys("111111")
time.sleep(2)
处理验证码并进行登录
solveCaptchaAndLogin(driver, "img/login/", "imgvercodeLogin", "verfieldUserText")
driver.findElementByXpath("//*[@id='loginForm']/div[6]/button").click() # 点击登录按钮
检查是否登录成功
var userName = driver.findElementByXpath("//*[@id='userWrap']/div/p").getText()
let expectedUserName = "用户1"
while userName != expectedUserName do
solveCaptchaAndLogin(driver, "img/login/", "imgvercodeLogin", "verfieldUserText")
driver.findElementByXpath("//[@id='loginForm']/div[6]/button").click() # 点击登录按钮
userName = driver.findElementByXpath("//[@id='userWrap']/div/p").getText()
end
echo "登录成功"
标签:截图,裁剪,登录,Nim,cstring,driver,验证码,let From: https://www.cnblogs.com/ocr12/p/18545549