Tesseract.js识别图片验证码

1,906 阅读1分钟

1. 概述

最近想尝试一下e2e自动化测试,项目开始使用jest-puppeteer,许多操作要只能使用其提供的API操作,常用的$eval等用了就报错,于是就放弃了,后来使用基于自定义环境版本jest-puppeteer-example进行开发,在本地写一写demo,还不成熟,先记录一下。

1666497034142.png

搞定了环境问题,接下来遇到第一个问题就是登录,登录中有一个验证码,测试的时候总不能手动填入吧,于是就用到了Tesseract.js

2. 依赖库

demo中用到了

{
    "@babel/core": "^7.19.0",
    "@babel/preset-env": "^7.19.0",
    "jest": "^29.0.2",
    "jest-puppeteer": "^6.1.1",
    "puppeteer": "^17.1.3",
    "tesseract.js": "^3.0.2"
}

3. 代码

用法也比较简单,需要注意的是,识别有一定几率会识别错误,导致登录失败,我这里做了识别失败的错误处理,一旦登录失败会二次识别重新输入并登录,知道输入正确,等成功。

1666496898481.png

toLogin.js

/**
 * 去登陆
 */
const toTypeCode = require('./toTypeCode.js');
const toLogin = (page, timeout) => {
  return new Promise(async (resolve, reject) => {
    await page.goto('http://xxx.com');
    await page.setViewport({ width: 1920, height: 1080 });
    await page.type('input[placeholder="员工编号"]', '023278');
    await page.type('input[placeholder="密码"]', '123456');
    await toTypeCode(page);
    resolve(page);
  });
};
module.exports = toLogin;

toTypeCode.js

/**
 * 去输入验证码
 */
const Tesseract = require('tesseract.js');
const toTypeCode = page => {
  return new Promise(async (resolve, reject) => {
    let url = await page.target().url();
    //获取验证码图片base64数据
    const base64Url = await page.$eval('.code-img>img', el => el.src); 
    //等待转换结果
    const res = await Tesseract.recognize(base64Url, 'eng', {}); 
    //提取转换后的数据
    const {
      data: { text },
    } = res; 
    await page.type('input[placeholder="验证码"]', '');
    await page.type('input[placeholder="验证码"]', text);
    await page.waitForTimeout(500); //等待url发生变化
    let url2 = await page.target().url();
    if (url == url2) {
      await toTypeCode(page);
    } else {
      await page.waitForTimeout(3000); //等待新页面渲染
      resolve();
    }
  });
};
module.exports = toTypeCode;