一、前言

使用tesseract3.02识别有验证码的网站 安装tesseract3.02 在VS nuget 搜索Tesseract即可。

二、项目结构图

三、项目主要代码

 using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Cache;
using System.Text; namespace Tesseract.Test.Tools
{
/// <summary>
/// http帮助类
/// </summary>
public class HttpHelper
{
/// <summary>
/// 异步事件
/// </summary>
public HttpHelper()
{
CookieContainer = new CookieContainer();
Encoding = Encoding.UTF8;
} /// <summary>
/// 访问次数字典
/// </summary>
private ConcurrentDictionary<String, int> urlTryList = new ConcurrentDictionary<string, int>(); /// <summary>
/// Cookie 容器
/// </summary>
public CookieContainer CookieContainer { set; get; } /// <summary>
/// Post数据
/// </summary>
public String PostData { set; private get; } /// <summary>
/// 页面语言
/// </summary>
public Encoding Encoding { set; private get; } /// <summary>
/// 验证码路径
/// </summary>
public string CodePath { get; set; } /// <summary>
/// 文件保存路径
/// </summary>
public String FileSavePath { set; private get; } /// <summary>
/// 回调时间
/// </summary>
public Action<String, String> CallBackAction; /// <summary>
/// 异步请求
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="tryTimes">错误重试次数</param>
public void AsynRequest(String url, int tryTimes = )
{
Trace.TraceInformation(String.Concat("开始异步请求:", url));
urlTryList.TryAdd(url, tryTimes);
var request = WebRequest.Create(url) as HttpWebRequest;
if (request == null) return;
request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate |
DecompressionMethods.None;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
request.UseDefaultCredentials = false;
request.KeepAlive = false;
request.PreAuthenticate = false;
request.ProtocolVersion = HttpVersion.Version10;
request.UserAgent =
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
//request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
request.Timeout = **;
request.CookieContainer = CookieContainer;
//request.AllowAutoRedirect = false; if (!String.IsNullOrEmpty(PostData))
{
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.BeginGetRequestStream(GetRequestStreamCallback, request);
}
else
{
//request.AllowReadStreamBuffering = false;
request.AllowWriteStreamBuffering = false;
request.BeginGetResponse(GetResponseCallback, request);
}
} /// <summary>
/// 开始对用来写入数据的 Stream 对象的异步请求。
/// </summary>
/// <param name="ar"></param>
private void GetRequestStreamCallback(IAsyncResult ar)
{
var request = ar.AsyncState as HttpWebRequest;
if (request == null) return;
var postStream = request.EndGetRequestStream(ar);
var byteArray = Encoding.GetBytes(PostData);
postStream.Write(byteArray, , PostData.Length);
postStream.Close();
request.BeginGetResponse(GetResponseCallback, request);
} /// <summary>
/// 开始对 Internet 资源的异步请求。
/// </summary>
/// <param name="ar"></param>
private void GetResponseCallback(IAsyncResult ar)
{
var request = ar.AsyncState as HttpWebRequest;
if (request == null) return;
try
{
using (var response = request.EndGetResponse(ar) as HttpWebResponse)
{
if (response != null)
{
//if (response.StatusCode == HttpStatusCode.Found)
//{
// string redirect = response.Headers["Location"];
// if (!String.IsNullOrEmpty(redirect)) AsynRequest(redirect);
// return;
//} if (response.StatusCode != HttpStatusCode.OK)
{
Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败,HttpStatusCode",
response.StatusCode));
return;
} using (var streamResponse = response.GetResponseStream())
{
if (streamResponse != null)
{
if (!IsText(response.ContentType))
{
var contentEncodingStr = response.ContentEncoding;
var contentEncoding = Encoding;
if (!String.IsNullOrEmpty(contentEncodingStr))
contentEncoding = Encoding.GetEncoding(contentEncodingStr);
using (var streamRead = new StreamReader(streamResponse, contentEncoding))
{
var str = streamRead.ReadToEnd();
if (CallBackAction != null && !String.IsNullOrEmpty(str))
CallBackAction.BeginInvoke(str, request.RequestUri.ToString(), (s) => { },
null);
}
}
else
{
var fileName = String.Concat(DateTime.Now.ToString("yyyyMMdd"), "/",
DateTime.Now.ToString("yyyyMMddHHmmssffff"),
//Extensions.String_.Extensions.GetRnd(6, true, false, false, false, String.Empty),
".jpg");
var fileDirectory = Path.Combine(FileSavePath, DateTime.Now.ToString("yyyyMMdd"));
CodePath = Path.Combine(FileSavePath, fileName);
if (!Directory.Exists(fileDirectory))
Directory.CreateDirectory(fileDirectory); //下载文件
using (
var fileStream = new FileStream(Path.Combine(FileSavePath, fileName),
FileMode.Create))
{
var buffer = new byte[];
int readLength;
do
{
readLength = streamResponse.Read(buffer, , buffer.Length);
fileStream.Write(buffer, , readLength);
} while (readLength != );
}
if (CallBackAction != null && !String.IsNullOrEmpty(fileName))
CallBackAction.BeginInvoke(fileName, request.RequestUri.ToString(), (s) => { },
null);
}
}
}
response.Close();
}
}
}
catch (WebException ex)
{
Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败信息:", ex.Message));
var toUrl = request.RequestUri.ToString();
int tryTimes;
if (urlTryList.TryGetValue(toUrl, out tryTimes))
{
urlTryList.TryUpdate(toUrl, tryTimes, tryTimes - );
if (tryTimes - <= )
{
urlTryList.TryRemove(toUrl, out tryTimes);
return;
}
AsynRequest(toUrl);
}
}
finally
{
request.Abort();
}
} /// <summary>
/// 同步请求
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="tryTimes">错误重试次数</param>
public String SyncRequest(String url, int tryTimes = )
{
Trace.TraceInformation(String.Concat("开始同步请求:", url));
urlTryList.TryAdd(url, tryTimes);
var request = WebRequest.Create(url) as HttpWebRequest;
if (request == null) return String.Empty;
request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate |
DecompressionMethods.None;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
request.UseDefaultCredentials = false;
request.KeepAlive = false;
request.PreAuthenticate = false;
request.ProtocolVersion = HttpVersion.Version10;
request.UserAgent =
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
request.Timeout = **;
request.CookieContainer = CookieContainer;
request.AllowAutoRedirect = true; if (!String.IsNullOrEmpty(PostData))
{
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
using (var postStream = request.GetRequestStream())
{
var byteArray = Encoding.GetBytes(PostData);
postStream.Write(byteArray, , PostData.Length);
postStream.Close();
}
}
else
{
//request.AllowReadStreamBuffering = false;
request.AllowWriteStreamBuffering = false;
}
try
{
using (var response = request.GetResponse() as HttpWebResponse)
{
if (response != null)
{
if (response.StatusCode != HttpStatusCode.OK)
{
Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败,HttpStatusCode",
response.StatusCode));
return String.Empty;
}
using (var streamResponse = response.GetResponseStream())
{
if (streamResponse != null)
{
if (!IsText(response.ContentType))
{
var contentEncodingStr = response.ContentEncoding;
var contentEncoding = Encoding;
if (!String.IsNullOrEmpty(contentEncodingStr))
contentEncoding = Encoding.GetEncoding(contentEncodingStr);
var streamRead = new StreamReader(streamResponse, contentEncoding);
var str = streamRead.ReadToEnd();
if (CallBackAction != null && !String.IsNullOrEmpty(str))
CallBackAction.BeginInvoke(str, request.RequestUri.ToString(), (s) => { }, null);
return str;
} var fileName = String.Concat(DateTime.Now.ToString("yyyyMMdd"), "/",
DateTime.Now.ToString("yyyyMMddHHmmssffff"),
//Extensions.String_.Extensions.GetRnd(6, true, false, false, false, String.Empty),
Path.GetExtension(request.RequestUri.AbsoluteUri));
var fileDirectory = Path.Combine(FileSavePath, DateTime.Now.ToString("yyyyMMdd"));
if (!Directory.Exists(fileDirectory))
Directory.CreateDirectory(fileDirectory); //下载文件
using (
var fileStream = new FileStream(Path.Combine(FileSavePath, fileName),
FileMode.Create))
{
var buffer = new byte[];
int readLength;
do
{
readLength = streamResponse.Read(buffer, , buffer.Length);
fileStream.Write(buffer, , readLength);
} while (readLength != );
}
if (CallBackAction != null && !String.IsNullOrEmpty(fileName))
CallBackAction.BeginInvoke(fileName, request.RequestUri.ToString(), (s) => { }, null);
return fileName;
}
}
response.Close();
}
}
}
catch (WebException ex)
{
Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败信息:", ex.Message));
var toUrl = request.RequestUri.ToString();
if (urlTryList.TryGetValue(toUrl, out tryTimes))
{
urlTryList.TryUpdate(toUrl, tryTimes, tryTimes - );
if (tryTimes - <= )
{
urlTryList.TryRemove(toUrl, out tryTimes);
Trace.TraceError(String.Concat("请求地址重试失败:", request.RequestUri));
return String.Empty;
}
SyncRequest(toUrl);
}
}
finally
{
request.Abort();
}
return String.Empty;
} /// <summary>
/// 验证码获取
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="tryTimes">错误重试次数</param>
public Bitmap GetCheckCode(String url, int tryTimes = )
{
Trace.TraceInformation(String.Concat("开始同步请求:", url));
urlTryList.TryAdd(url, tryTimes);
var request = WebRequest.Create(url) as HttpWebRequest;
if (request == null) return null;
request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate |
DecompressionMethods.None;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
request.UseDefaultCredentials = false;
request.KeepAlive = false;
request.PreAuthenticate = false;
request.ProtocolVersion = HttpVersion.Version10;
request.UserAgent =
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
request.Timeout = **;
request.CookieContainer = CookieContainer;
request.AllowAutoRedirect = true; if (!String.IsNullOrEmpty(PostData))
{
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
using (var postStream = request.GetRequestStream())
{
var byteArray = Encoding.GetBytes(PostData);
postStream.Write(byteArray, , PostData.Length);
postStream.Close();
}
}
else
{
//request.AllowReadStreamBuffering = false;
request.AllowWriteStreamBuffering = false;
}
try
{
using (var response = request.GetResponse() as HttpWebResponse)
{
if (response != null)
{
if (response.StatusCode != HttpStatusCode.OK)
{
Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败,HttpStatusCode",
response.StatusCode));
return null;
}
using (var streamResponse = response.GetResponseStream())
{
if (streamResponse != null)
{
return (Bitmap) Bitmap.FromStream(streamResponse);
}
}
response.Close();
}
}
}
catch (WebException ex)
{
Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败信息:", ex.Message));
var toUrl = request.RequestUri.ToString();
if (urlTryList.TryGetValue(toUrl, out tryTimes))
{
urlTryList.TryUpdate(toUrl, tryTimes, tryTimes - );
if (tryTimes - <= )
{
urlTryList.TryRemove(toUrl, out tryTimes);
Trace.TraceError(String.Concat("请求地址重试失败:", request.RequestUri));
return null;
}
GetCheckCode(toUrl);
}
}
finally
{
request.Abort();
}
return null;
} /// <summary>
/// 判断文件是否为文本类型
/// </summary>
/// <param name="contentType">内容类型</param>
/// <returns></returns>
private static bool IsText(String contentType)
{
var fileContentType = new List<string>
{
"image/Bmp",
"image/gif",
"image/jpeg",
"image/png",
"image/tiff",
"application/octet-stream"
};
return fileContentType.Contains(contentType);
}
}
}

HttpHepler

 using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.InteropServices; namespace Tesseract.Test.Tools
{
public class UnCodebase
{
public Bitmap bmpobj; public UnCodebase(Bitmap pic)
{
bmpobj = new Bitmap(pic); //转换为Format32bppRgb
} /// <summary>
/// 根据RGB,计算灰度值
/// </summary>
/// <param name="posClr">Color值</param>
/// <returns>灰度值,整型</returns>
private int GetGrayNumColor(Color posClr)
{
return (posClr.R* + posClr.G* + posClr.B*) >> ;
} /// <summary>
/// 灰度转换,逐点方式
/// </summary>
public Bitmap GrayByPixels()
{
for (int i = ; i < bmpobj.Height; i++)
{
for (int j = ; j < bmpobj.Width; j++)
{
int tmpValue = GetGrayNumColor(bmpobj.GetPixel(j, i));
bmpobj.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));
}
}
return bmpobj;
} /// <summary>
/// 去图形边框
/// </summary>
/// <param name="borderWidth"></param>
public Bitmap ClearPicBorder(int borderWidth)
{
for (int i = ; i < bmpobj.Height; i++)
{
for (int j = ; j < bmpobj.Width; j++)
{
if (i < borderWidth || j < borderWidth || j > bmpobj.Width - - borderWidth ||
i > bmpobj.Height - - borderWidth)
bmpobj.SetPixel(j, i, Color.FromArgb(, , ));
}
}
return bmpobj;
} /// <summary>
/// 灰度转换,逐行方式
/// </summary>
public Bitmap GrayByLine()
{
Rectangle rec = new Rectangle(, , bmpobj.Width, bmpobj.Height);
BitmapData bmpData = bmpobj.LockBits(rec, ImageLockMode.ReadWrite, bmpobj.PixelFormat);
// PixelFormat.Format32bppPArgb);
// bmpData.PixelFormat = PixelFormat.Format24bppRgb;
IntPtr scan0 = bmpData.Scan0;
int len = bmpobj.Width*bmpobj.Height;
int[] pixels = new int[len];
Marshal.Copy(scan0, pixels, , len); //对图片进行处理
int GrayValue = ;
for (int i = ; i < len; i++)
{
GrayValue = GetGrayNumColor(Color.FromArgb(pixels[i]));
pixels[i] = (byte) (Color.FromArgb(GrayValue, GrayValue, GrayValue)).ToArgb(); //Color转byte
} bmpobj.UnlockBits(bmpData);
return bmpobj;
} /// <summary>
/// 得到有效图形并调整为可平均分割的大小
/// </summary>
/// <param name="dgGrayValue">灰度背景分界值</param>
/// <param name="CharsCount">有效字符数</param>
/// <returns></returns>
public void GetPicValidByValue(int dgGrayValue, int CharsCount)
{
int posx1 = bmpobj.Width;
int posy1 = bmpobj.Height;
int posx2 = ;
int posy2 = ;
for (int i = ; i < bmpobj.Height; i++) //找有效区
{
for (int j = ; j < bmpobj.Width; j++)
{
int pixelValue = bmpobj.GetPixel(j, i).R;
if (pixelValue < dgGrayValue) //根据灰度值
{
if (posx1 > j) posx1 = j;
if (posy1 > i) posy1 = i; if (posx2 < j) posx2 = j;
if (posy2 < i) posy2 = i;
}
;
}
;
}
;
// 确保能整除
int Span = CharsCount - (posx2 - posx1 + )%CharsCount; //可整除的差额数
if (Span < CharsCount)
{
int leftSpan = Span/; //分配到左边的空列 ,如span为单数,则右边比左边大1
if (posx1 > leftSpan)
posx1 = posx1 - leftSpan;
if (posx2 + Span - leftSpan < bmpobj.Width)
posx2 = posx2 + Span - leftSpan;
}
//复制新图
Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + , posy2 - posy1 + );
bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
} /// <summary>
/// 得到有效图形,图形为类变量
/// </summary>
/// <param name="dgGrayValue">灰度背景分界值</param>
/// <param name="CharsCount">有效字符数</param>
/// <returns></returns>
public void GetPicValidByValue(int dgGrayValue)
{
int posx1 = bmpobj.Width;
int posy1 = bmpobj.Height;
int posx2 = ;
int posy2 = ;
for (int i = ; i < bmpobj.Height; i++) //找有效区
{
for (int j = ; j < bmpobj.Width; j++)
{
int pixelValue = bmpobj.GetPixel(j, i).R;
if (pixelValue < dgGrayValue) //根据灰度值
{
if (posx1 > j) posx1 = j;
if (posy1 > i) posy1 = i; if (posx2 < j) posx2 = j;
if (posy2 < i) posy2 = i;
}
;
}
;
}
;
//复制新图
Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + , posy2 - posy1 + );
bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
} /// <summary>
/// 得到有效图形,图形由外面传入
/// </summary>
/// <param name="dgGrayValue">灰度背景分界值</param>
/// <param name="CharsCount">有效字符数</param>
/// <returns></returns>
public Bitmap GetPicValidByValue(Bitmap singlepic, int dgGrayValue)
{
int posx1 = singlepic.Width;
int posy1 = singlepic.Height;
int posx2 = ;
int posy2 = ;
for (int i = ; i < singlepic.Height; i++) //找有效区
{
for (int j = ; j < singlepic.Width; j++)
{
int pixelValue = singlepic.GetPixel(j, i).R;
if (pixelValue < dgGrayValue) //根据灰度值
{
if (posx1 > j) posx1 = j;
if (posy1 > i) posy1 = i; if (posx2 < j) posx2 = j;
if (posy2 < i) posy2 = i;
}
;
}
;
}
;
//复制新图
Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + , posy2 - posy1 + );
return singlepic.Clone(cloneRect, singlepic.PixelFormat);
} /// <summary>
/// 平均分割图片
/// </summary>
/// <param name="RowNum">水平上分割数</param>
/// <param name="ColNum">垂直上分割数</param>
/// <returns>分割好的图片数组</returns>
public Bitmap[] GetSplitPics(int RowNum, int ColNum)
{
if (RowNum == || ColNum == )
return null;
int singW = bmpobj.Width/RowNum;
int singH = bmpobj.Height/ColNum;
Bitmap[] PicArray = new Bitmap[RowNum*ColNum]; Rectangle cloneRect;
for (int i = ; i < ColNum; i++) //找有效区
{
for (int j = ; j < RowNum; j++)
{
cloneRect = new Rectangle(j*singW, i*singH, singW, singH);
PicArray[i*RowNum + j] = bmpobj.Clone(cloneRect, bmpobj.PixelFormat); //复制小块图
}
}
return PicArray;
} /// <summary>
/// 返回灰度图片的点阵描述字串,1表示灰点,0表示背景
/// </summary>
/// <param name="singlepic">灰度图</param>
/// <param name="dgGrayValue">背前景灰色界限</param>
/// <returns></returns>
public string GetSingleBmpCode(Bitmap singlepic, int dgGrayValue)
{
Color piexl;
string code = "";
for (int posy = ; posy < singlepic.Height; posy++)
for (int posx = ; posx < singlepic.Width; posx++)
{
piexl = singlepic.GetPixel(posx, posy);
if (piexl.R < dgGrayValue) // Color.Black )
code = code + "";
else
code = code + "";
}
return code;
} /// <summary>
/// 去掉噪点
/// </summary>
/// <param name="dgGrayValue"></param>
/// <param name="MaxNearPoints"></param>
public Bitmap ClearNoise(int dgGrayValue, int MaxNearPoints)
{
Color piexl;
int nearDots = ;
int XSpan, YSpan, tmpX, tmpY;
//逐点判断
for (int i = ; i < bmpobj.Width; i++)
for (int j = ; j < bmpobj.Height; j++)
{
piexl = bmpobj.GetPixel(i, j);
if (piexl.R < dgGrayValue)
{
nearDots = ;
//判断周围8个点是否全为空
if (i == || i == bmpobj.Width - || j == || j == bmpobj.Height - ) //边框全去掉
{
bmpobj.SetPixel(i, j, Color.FromArgb(, , ));
}
else
{
if (bmpobj.GetPixel(i - , j - ).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i, j - ).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i + , j - ).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i - , j).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i + , j).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i - , j + ).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i, j + ).R < dgGrayValue) nearDots++;
if (bmpobj.GetPixel(i + , j + ).R < dgGrayValue) nearDots++;
} if (nearDots < MaxNearPoints)
bmpobj.SetPixel(i, j, Color.FromArgb(, , )); //去掉单点 && 粗细小3邻边点
}
else //背景
bmpobj.SetPixel(i, j, Color.FromArgb(, , ));
}
return bmpobj;
} /// <summary>
/// 扭曲图片校正
/// </summary>
public Bitmap ReSetBitMap()
{
Graphics g = Graphics.FromImage(bmpobj);
Matrix X = new Matrix();
// X.Rotate(30);
X.Shear((float) 0.16666666667, ); // 2/12
g.Transform = X;
// Draw image
//Rectangle cloneRect = GetPicValidByValue(128); //Get Valid Pic Rectangle
Rectangle cloneRect = new Rectangle(, , bmpobj.Width, bmpobj.Height);
Bitmap tmpBmp = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
g.DrawImage(tmpBmp,
new Rectangle(, , bmpobj.Width, bmpobj.Height),
, , tmpBmp.Width,
tmpBmp.Height,
GraphicsUnit.Pixel); return tmpBmp;
}
}
}

UnCodebase

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tesseract.Test.Tools; namespace Tesseract.Test
{
/// <summary>
/// 网站用户
/// </summary>
public class WebUser
{
/// <summary>
/// 用户名
/// </summary>
private string _userName = string.Empty; /// <summary>
/// 密码
/// </summary>
private string _password = string.Empty; /// <summary>
/// 验证码
/// </summary>
private string _checkCode = string.Empty; private HttpHelper _httpHelper = new HttpHelper(); /// <summary>
/// 构造函数
/// </summary>
public WebUser()
{
_userName = "admin"; //初始化用户
_password = "password"; //初始化密码
Login();
} /// <summary>
/// 登录
/// </summary>
private void Login()
{
//登录页
_httpHelper.SyncRequest("Login.html"); //获取验证码图片
var bitmap = _httpHelper.GetCheckCode("CheckCode.html"); //解析验证码
using (var engine = new TesseractEngine(@"./tessdata", "eng", EngineMode.Default))
{
using (var entity = engine.Process(bitmap))
{
_checkCode = entity.GetText();
}
} //登录验证
_httpHelper.PostData = string.Format("userName={0}&password={1}&checkcode={2}",
_userName, _password, _checkCode);
_httpHelper.SyncRequest("CheckLogin.html");
}
}
}

WebUser

四、代码解释

1、模拟登录的过程基本都是访问登录页面获取相关的cookie。

2、访问验证码页面这样就不用将验证码下载到本地再解析。直接在程序内解析。减少验证码本地图片文件增加。

3、使用tesseract来解析验证码。(需要看验证码的干扰是否严重,使用UnCodebase对验证码图片适当的处理可以增加识别正确率)

4、访问登录验证页面将用户名密码验证码POST过去。

5、登录成功。

C#使用tesseract3.02识别验证码模拟登录的更多相关文章

  1. C#使用tesseract3.02识别验证码模拟登录(转)

    转自http://www.cnblogs.com/JinJi-Jary/p/5625414.html

  2. tesseract3.02识别验证码需要注意的问题

    1.安装tesseract3.02后,在命令行里输入tesseract,看能否出现使用方法,不出现则是环境变量问题,可调整其顺序. 2.找到如下文件 C:\Python27\Lib\site-pack ...

  3. 验证码模拟登录TestHome

    前面我们做了一个xsrf的知乎的模拟登录,那么今天将会给大家分享一下小弟写的一段带验证码的登录脚本.   今天我们要做的是testerhome的模拟登录,在做这个模拟登录的时候,我发现需要验证码才能登 ...

  4. Python3.7爬虫:实时api(百度ai)检测验证码模拟登录(Selenium)页面

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_134 今天有同学提出了一个需求,老板让自动登录这个页面:https://www.dianxiaomi.com/index.htm, ...

  5. Python之selenium+pytesseract 实现识别验证码自动化登录脚本

    今天写自己的爆破靶场WP时候,遇到有验证码的网站除了使用pkav的工具我们同样可以通过py强大的第三方库来实现识别验证码+后台登录爆破,这里做个笔记~~~ 0x01关于selenium seleniu ...

  6. qtp识别验证码

    花了两天时间才完整的完成识别验证码的登录操作,在网上看到很多关于验证码识别的方法,但是我用的qtp版本比较高级,所以还是要自己花心思研究.po上我的识别验证码的详细历程: 一.读取浏览器中的图片验证码 ...

  7. 用python模拟登录(解析cookie + 解析html + 表单提交 + 验证码识别 + excel读写 + 发送邮件)

    老婆大人每个月都要上一个网站上去查数据,然后做报表. 为了减轻老婆大人的工作压力,所以我决定做个小程序,减轻我老婆的工作量. 准备工作 1.tesseract-ocr 这个工具用来识别验证码,非常好用 ...

  8. Java豆瓣电影爬虫——模拟登录的前世今生与验证码的爱恨情仇

    前言 并不是所有的网站都能够敞开心扉让你看个透彻,它们总要给你出些难题让你觉得有些东西是来之不易的,往往,这也更加激发你的激情和斗志! 从<为了媳妇的一张号,我与百度医生杠上了>里就有网友 ...

  9. php通过curl扩展进行模拟登录(含验证码)

    以下为本人工作中遇到的需要做的事情,之前也没怎么用过curl,查了好多资料,才稍微弄明白一点:本文所有内容只是自己平日工作的记录,仅供大家参考:<?php/*** 模拟登录*/header(&q ...

随机推荐

  1. Ubuntu18.04修改Hostname

    1. 设置新的hostnamesudo hostnamectl set-hostname newNameHere 2. 修改配置文件使hostname可以保存编辑这个文件: /etc/cloud/cl ...

  2. 基本类型转换成NSNumber类型

    int i=100; float f=2.34; NSNumber *n1=[NSNumber numberWithInt:i]; NSNumber *n2=[NSNumber numberWithF ...

  3. Elasticsearch部署异常Permission denied

    异常描述 在Linux上部署ElasticSearch时抛出了一个异常如下: log4j:ERROR setFile(null,true) call failed. java.io.FileNotFo ...

  4. Maven 学习笔记(三)

    有时我们在项目中可能需要打包一个可执行的 jar 包,我最近也遇见了,很傻很天真的用了如下配置: <packaging>jar</packaging> 效果一如既往的好,打包成 ...

  5. SqlServer Function 实例

    ① sql server function 创建 这里使用一个计算年龄精确到分的function作为一个demo, create Function [dbo].[fn_GetAge] ( @BIRTH ...

  6. Android蓝牙2.0连接以及数据接收发送

    1.加入权限 <uses-feature android:name="android.hardware.bluetooth_le" android:required=&quo ...

  7. 我的nginx+php是如何配置的?

    nginx使用homebrew安装,安装之后 ngxin 安装目录:/usr/local/Cellar/nginx/1.8.0 删除掉默认的www目录,创建一个自己方便找到的 删除掉默认的www目录 ...

  8. js浏览器问题

    前段时间做了个项目,里面关于手机移动端下载的问题 开始是判断微信.ios和android系统的下载 因为微信屏蔽点击事件和链接的缘故,需要通过打开新页面来进行下载 ios和android的下载分别为不 ...

  9. java开发移动端之spring的restful风格定义

    https://www.ibm.com/developerworks/cn/web/wa-spring3webserv/index.html

  10. npm run eject 命令后出现This git repository has untracked files or uncommitted changes错误

    npm run eject 暴露隐藏的文件,不可逆 结果出现下面的问题 This git repository has untracked files or uncommitted changes: ...