e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (二) 图片验证码的识别
上一篇文章讲了“e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step 一 京东 商品搜索”
关于图片验证码的识别, 有多种方法, 之前有在Google, baidu上找了非常多的文章, 有非常多的方法去实现 ,但我学得使用 Google赞助的tesseract 工具,是比较不错的选择。tesseract是一个exe, 其实本文章实际上与Node.js已经没有太大的关系。因为我们要做的是如果调用这个exe.
保存验证码图片
WebdriverIo, 提供了一个接口为 saveScreenshot 就是可以保证当前页面的屏幕截图。 如下:
首先是打开一个新的窗口, captchaUrl,就是图片验证码的url地址, 如JD的是 https://authcode.jd.com/verify/image?a=1&acid=72c69aa3-7ffc-4934-b8cc-199750307af6&uid=72c69aa3-7ffc-4934-b8cc-199750307af6&yys=1413969656908%22, 放在IE中, F5,不停的刷新,你会发现,他在不停的变化。
就是保存屏幕截图。将图片存放在本地, Node.js 支持调用本地的exe, 请参考 http://nodejs.org/api/process.html 实际上就是执行CMD命令。tesseract 执行如 CMD > tesseract z:\snapshot.pgn result 执行后会在当前目录生成一个txt文件,内容就是识别后的文本。
但是在此, 为了提高识别的概率, 我会先将图片灰度化,然后再生成一张黑白图片, 最后给tesseract 支识别, 使用Node.js会比较麻烦, 所以我使用的.net c#实现, 然后做成一个服务 API, 然后,让Node.js去调用。
C#的内容如下:
[RoutePrefix("api/CaptchaDecoder")]
public class CaptchaDecoderController : ApiController
{
ILog log = LogManager.GetLogger("AppLog");
TesseractService _tesseract;
public CaptchaDecoderController()
{
log4net.Config.DOMConfigurator.Configure();
_tesseract = new TesseractService();
}
public CaptchaDecoderController(TesseractService tesseract)
{
_tesseract = tesseract;
}
[HttpPost]
public ServicePostResponse CaptchaDecoder(ServicePostRequest<CaptchaModel> request)
{
var response = new ServicePostResponse();
try
{
if(request == null)
{
throw new Exception("request is null");
}
if (string.IsNullOrEmpty(request.ExtraData.SystemId))
{
throw new Exception("request.ExtraData.SystemId is null or empty");
}
if (string.IsNullOrEmpty(request.ExtraData.FilePath))
{
throw new Exception("request.ExtraData.FilePath is null or empty");
}
var filePath = request.ExtraData.FilePath;
if (!File.Exists(filePath))
{
throw new Exception("File:" + request.ExtraData.FilePath + " doesn't exist");
}
using (Bitmap sourceBmp = new Bitmap(filePath))
{
GetGrayBitmap(sourceBmp);
GetBackWhiteBitmapNew(sourceBmp);
Bitmap bmp = ClearNoise(sourceBmp, 3);
bmp.Save(filePath + "_new.jpg");
fnOCR(@_tesseract.exePath, @filePath + "_new.jpg " + filePath + "_result nobatch digits");
if (File.Exists(filePath + "_result.txt"))
{
using (StreamReader file = File.OpenText(filePath + "_result.txt"))
{
response.ExtraData = file.ReadLine();
file.Close();
}
}
else
{
throw new Exception("generate the result fail");
}
bmp.Dispose();
sourceBmp.Dispose();
}
response.IsSuccess = true;
response.Total = 1;
}
catch (Exception ex)
{
log.Error(ex);
response.Errors = ex.Message;
response.IsSuccess = false;
response.Total = 0;
}
finally
{
}
return response;
}
private string GetCurrentSeqValue()
{
return System.DateTime.Now.Month.ToString("00");
}
private void GetGrayBitmap(Bitmap bmp)
{
for (int i = 0; i < bmp.Width; i++)
{
for (int j = 0; j < bmp.Height; j++)
{
//获取该点的像素的RGB的颜色
Color color = bmp.GetPixel(i, j);
//利用公式计算灰度值
int gray = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);
Color newColor = Color.FromArgb(gray, gray, gray);
bmp.SetPixel(i, j, newColor);
}
}
}
private void GetBackWhiteBitmap(Bitmap bitmap)
{
int v = ImageHelper.ComputeThresholdValue(bitmap);
ImageHelper.PBinary(bitmap, v);
}
private void GetBackWhiteBitmapNew(Bitmap bmp)
{
int average = 0;
for (int i = 0; i < bmp.Width; i++)
{
for (int j = 0; j < bmp.Height; j++)
{
Color color = bmp.GetPixel(i, j);
average += color.B;
}
}
average = (int)(average * 1.0 / (bmp.Width * bmp.Height));
}
public Bitmap ClearNoise(Bitmap bmpobj, int MaxNearPoints)
{
int dgGrayValue = ImageHelper.ComputeThresholdValue(bmpobj);
Color piexl;
Bitmap bmp = new Bitmap(bmpobj);
int nearDots = 0;
//逐点判断
for (int i = 0; i < bmpobj.Width; i++)
for (int j = 0; j < bmpobj.Height; j++)
{
piexl = bmpobj.GetPixel(i, j);
if (piexl.R <= dgGrayValue)
{
nearDots = 0;
//判断周围8个点是否全为空
if (i == 0 || i == bmpobj.Width - 1 || j == 0 || j == bmpobj.Height - 1) //边框全去掉
{
bmp.SetPixel(i, j, Color.White);
}
else
{
if (bmpobj.GetPixel(i - 1, j - 1).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i, j - 1).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i + 1, j - 1).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i - 1, j).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i + 1, j).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i - 1, j + 1).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i, j + 1).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i + 1, j + 1).R < dgGrayValue) nearDots++;
}
if (nearDots <= MaxNearPoints)
bmp.SetPixel(i, j, Color.White); //去掉单点 && 粗细小3邻边点
}
else //背景
bmp.SetPixel(i, j, Color.White);
}
return bmp;
}
private void fnOCR(string v_strTesseractPath, string v_Arguments)
{
using (Process process = new System.Diagnostics.Process())
{
process.StartInfo.FileName = v_strTesseractPath;
process.StartInfo.Arguments = v_Arguments;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
process.WaitForExit();
}
}
}
public class TesseractService
{
public virtual string exePath { get {
return @"C:\Program Files (x86)\Tesseract-OCR\tesseract.exe";
} }
}
上面的代码是ASP.NET WEBAPI应用。
最后,通Node.js的Http模块的功能,可以调用这个服务如下:
var http = require('http')
, fs = require('fs')
function decoderCaptchaECommerce(siteName, callback){
var requestData = {
ExtraData: {
SystemId : siteName,
FilePath : 'Z:\\snapshot.png'
}
};
var requestDataString = JSON.stringify(requestData);
var headers = {
'Content-Type': 'application/json',
'Content-Length': requestDataString.length
};
var options = {
host: '127.1.1.1'
, port: 80
, path: '/api/CaptchaDecoder/CaptchaDecoder'
, method : 'POST'
, headers: headers
};
var responseString = '';
var req = http.request(options, function(res){
res.setEncoding('utf-8');
res.on('data', function(data){
responseString += data;
console.log("验证服务结果:"+responseString);
});
res.on('end', function(){
var resultObject = JSON.parse(responseString);
callback(resultObject.ExtraData);
})
});
req.on('error', function(e) {
// TODO: handle error.
});
req.write(requestDataString);
req.end();
return responseString;
};
e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (二) 图片验证码的识别的更多相关文章
- e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (六) 自动化测试结构小节
上一篇‘e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (五) 如何让窗体记录登录 ...
- e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (四) Q 反回调
上一篇文章“e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (三) SqlServ ...
- e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (三) SqlServer数据库的访问
上一篇文章“e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step 二 图片验证码的识别” ...
- e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (一) 京东 商品搜索
之前有发布一篇文章“e2e 自动化集成测试 环境搭建 Node.js Selenium WebDriverIO Mocha Node-Inspector”, 主要是讲了,如何搭建环境, 其中开发环境使 ...
- e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (五) 如何让窗体记录登录状态Session
在写自动化测试的Node.js脚本时, 时常需要测试所写的case, 可能都需要去重新登录一遍,这将相当的耗时, 好在Selenium都借了Session的机制, 如果在最初的浏览器没有关闭的情况下, ...
- e2e 自动化集成测试 环境搭建 Node.js Selenium WebDriverIO Mocha Node-Inspector
Node.js已经出来了许多年载,至今才开始接触.周未在家闲来无事,一时心血来潮,Google了大量的文章,经过实验,终于可以把整个环境给搭起来, 废话不多话,请看步骤. 特别注意, 本文章是针对Wi ...
- 前端自动化之路之gulp,node.js
随着现在前端技术的不断发展,和各个公司对前端项目开发更新速度的要求,前端自动化越来越受到大家的重视,之前传统的前端开发方式已经越来越不能满足开发的需求了,于是各种自动化工具随之产生了.而gulp就是其 ...
- 【nodejs笔记1】配置webstorm + node.js +express + mongodb开发博客的环境
1. 安装webstorm 并破解 2. 安装node (以及express框架) 至官网下载并安装.(http://nodejs.org)v0.10.32 msi 安装后测试,打开命令行, c ...
- WebStorm+Node.js开发环境的配置
1 下载地址: webstorm:http://www.jetbrains.com/webstorm node.js:https://nodejs.org/download/ 2 安装node.js ...
随机推荐
- Jquery异步请求简单实例(转)
本文引用自Xingsoft. 一.Jquery向aspx页面请求数据 前台页面JS代码: $("#Button1").bind("click&qu ...
- 微软Hololens学院教程-Hologram 230-空间场景建模(Spatial mapping )【微软教程已经更新,本文是老版本】
这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦!原文链接:https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/ho ...
- Gnome 插件介绍
插件:Applications Menuhttps://extensions.gnome.org/extension/6/applications-menu/ TopIconshttps://exte ...
- c++ 异常处理 assert | try
#include <iostream> #include <cassert> using namespace std; int main() { ; assert(i == ) ...
- Mybatis 一对一、一对多、多对多关联之级联添加
示例项目:MIPO_CRM 一.一对一关联 示例:订单与销售机会 描述:在业务员与客户的联系人的联系记录中可以生成一条销售机会,而此条销售机会可生成一条订单,两者呈一对一关联. 1.表设计 oppor ...
- Mybatis的分页查询
示例1:查询业务员的联系记录 1.控制器代码(RelationController.java) //分页列出联系记录 @RequestMapping(value="toPage/custom ...
- uc/os任务创建
问题描述: uc/os中任务创建 问题解决: 创建一个任务,任务从无到有.任务创建函数分两种, 一种是基本的创建函数OSTaskCreate, 另一种是扩展的任务创建函数OSTaskCrea ...
- The 6th Zhejiang Provincial Collegiate Programming Contest->ProblemA:Second-price Auction
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3202 题意:拍卖东西,以第二高价的价格卖给出第一高价的人.输出最后获得东西 ...
- Window8 进不了PE如何设置BIOS
如题,如今进入Win8时代,很多新出的机器都自带了WIN8.但是童鞋们想进PE进行操作的时候,发现进不了. 更改BIOS以下2处设置,即可使用第三方引导安装系统:Boot->Launch CSM ...
- HDU4647+贪心
/* 贪心. 题意:给定一些点 一些边 点和边都有价值.现在A B 选点.求A-B的maxVal 思路:分割边.边的1/2分给两个端点. 如果这两个点被同一个人取,则ok:否则 做减法也行,对题意无影 ...