上一篇文章讲了“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 (二) 图片验证码的识别的更多相关文章

  1. e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (六) 自动化测试结构小节

    上一篇‘e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (五) 如何让窗体记录登录 ...

  2. e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (四) Q 反回调

    上一篇文章“e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (三) SqlServ ...

  3. e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (三) SqlServer数据库的访问

    上一篇文章“e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step 二 图片验证码的识别” ...

  4. e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (一) 京东 商品搜索

    之前有发布一篇文章“e2e 自动化集成测试 环境搭建 Node.js Selenium WebDriverIO Mocha Node-Inspector”, 主要是讲了,如何搭建环境, 其中开发环境使 ...

  5. e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (五) 如何让窗体记录登录状态Session

    在写自动化测试的Node.js脚本时, 时常需要测试所写的case, 可能都需要去重新登录一遍,这将相当的耗时, 好在Selenium都借了Session的机制, 如果在最初的浏览器没有关闭的情况下, ...

  6. e2e 自动化集成测试 环境搭建 Node.js Selenium WebDriverIO Mocha Node-Inspector

    Node.js已经出来了许多年载,至今才开始接触.周未在家闲来无事,一时心血来潮,Google了大量的文章,经过实验,终于可以把整个环境给搭起来, 废话不多话,请看步骤. 特别注意, 本文章是针对Wi ...

  7. 前端自动化之路之gulp,node.js

    随着现在前端技术的不断发展,和各个公司对前端项目开发更新速度的要求,前端自动化越来越受到大家的重视,之前传统的前端开发方式已经越来越不能满足开发的需求了,于是各种自动化工具随之产生了.而gulp就是其 ...

  8. 【nodejs笔记1】配置webstorm + node.js +express + mongodb开发博客的环境

    1. 安装webstorm 并破解 2. 安装node (以及express框架) 至官网下载并安装.(http://nodejs.org)v0.10.32   msi  安装后测试,打开命令行, c ...

  9. WebStorm+Node.js开发环境的配置

    1 下载地址:  webstorm:http://www.jetbrains.com/webstorm node.js:https://nodejs.org/download/ 2 安装node.js ...

随机推荐

  1. webx学习笔记

    Webx学习笔记周建旭 2014-08-01 Webx工作流程 图 3.2. Webx Framework如何响应请求 当Webx Framework接收到一个来自WEB的请求以后,实际上它主要做了两 ...

  2. DB天气app冲刺二阶段第一天

    原来找人也是个力气活...好费劲呀..今天的进度有点慢,,确切的说是没有什么进度 因为不会弄了..加上今天一个劲的找同学帮忙写评论.心思没定下来 根本没思路了..明天按照今天的计划继续冲刺..

  3. What is an eigenvector of a covariance matrix?

    What is an eigenvector of a covariance matrix? One of the most intuitive explanations of eigenvector ...

  4. TaskTracker执行map或reduce任务的过程(二)

    上次说到,当MapLauncher或ReduceLancher(用于执行任务的线程,它们扩展自TaskLauncher),从它们所维护的LinkedList也即队列中获取到TaskInProgress ...

  5. 一分钟明白 VS manifest 原理

    什么是vs 程序的manifest文件 manifest 是VS程序用来标明所依赖的side-by-side组建,如ATL, CRT等的清单. 为什么要有manifest文件 一台pc上,用一组建往往 ...

  6. tomcat部署javaweb项目的三种方式

    一.将项目文件夹或war包直接拷贝到tomcat的webapps下 二.在Tomcat\conf\Catalina\localhost下建立xml文件 修改内容如下<Context path=& ...

  7. android 设置gridView item的高度

    public View getView(int position, View convertView, ViewGroup parent) { convertView = LayoutInflater ...

  8. PHP基础语法3

    文件系统 判断文件是否存在 如果只是判断文件存在,使用file_exists就行,file_exists不仅可以判断文件是否存在,同时也可以判断目录是否存在,从函数名可以看出, is_file是确切的 ...

  9. Qt:QT右键菜单

    Qt QTableView 上加右键弹出菜单, 并复制选中的单元格内容到剪贴板中 http://wenku.baidu.com/view/c51cfb63cf84b9d528ea7a29.html h ...

  10. CentOS SSH安装与配置

    SSH 为 Secure Shell 的缩写,由 IETF 的网络工作小组(Network Working Group)所制定:SSH 为建立在应用层和传输层基础上的安全协议. 传 统的网络服务程序, ...