上一篇文章讲了“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. H2嵌入式数据库的各种连接方式

    H2database是一款用java语言编写的开源数据库, 一般用作游戏的数据存储, 当然web项目也是可以用的, web项目也可以将该数据库 首先要安装H2数据库 http://www.h2data ...

  2. Linux必学的60个命令

    inux必学的60个命令Linux提供了大量的命令,利用它可以有效地完成大量的工作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在Linux系统上工作离不开使用系统提供的命令.要想 ...

  3. 实时数据处理环境搭建flume+kafka+storm:1.zookeeper 安装配置

    1. 解压 tar -zxvf 2.创建目录  zk根目录创建         mkdir zkdatalog  --日志          mkdir zkdata  ---快照文件 3.修改配置文 ...

  4. Cookie Session Cache

    二. 工作机制 Ø Cookie :采用的是客户端保存信息的方案. Ø Session :采用服务器端保存信息的方案. Ø Cache :利用缓存 SRAM 来"静态"的保存写入信 ...

  5. 1058: [ZJOI2007]报表统计 - BZOJ

    Description 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一.经过仔细观察,小Q发现统计一张报表实际上是维护一个非 ...

  6. [转载]C#设置开机启动

    原理就是在注册表启动项里添加一项.路径:SOFTWARE\Microsoft\Windows\CurrentVersion\Run或者直接:运行->regedit找到这个路径添加一项. usin ...

  7. 用MT.exe将exe中的manifest文件提取出来和将manifest文件放入exe中

     前一种方法是将manifest文件放入exe中,但是要记得需要在工程中设置 这样的话exe中就不存在manifest了,在debug目录下就会看到相应的manifest文件.后者是将exe中的man ...

  8. 关于DJANGO和JAVASCRIPT的时间

    最近,实际一些简单统计时,要到库里去检索数据出来用HIGHCHARTS画图, 作一个简单的回照.. DJANGO用TEMPLATEVIEW来作.专业,正规:) class SAView(Templat ...

  9. JavaScript 三种创建对象的方法

    JavaScript中对象的创建有以下几种方式: (1)使用内置对象 (2)使用JSON符号 (3)自定义对象构造 一.使用内置对象 JavaScript可用的内置对象可分为两种: 1,JavaScr ...

  10. Java中JSON的简单使用与前端解析

    http://www.blogjava.net/qileilove/archive/2014/06/13/414694.html 一.JSON JSON(JavaScript Object Notat ...