码迷,mamicode.com
首页 > Windows程序 > 详细

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

时间:2016-06-29 00:58:45      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:

一、前言

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

二、项目结构图

技术分享

三、项目主要代码

技术分享
  1 using System;
  2 using System.Collections.Concurrent;
  3 using System.Collections.Generic;
  4 using System.Diagnostics;
  5 using System.Drawing;
  6 using System.IO;
  7 using System.Net;
  8 using System.Net.Cache;
  9 using System.Text;
 10 
 11 namespace Tesseract.Test.Tools
 12 {
 13     /// <summary>
 14     /// http帮助类
 15     /// </summary>
 16     public class HttpHelper
 17     {
 18         /// <summary>
 19         /// 异步事件
 20         /// </summary>
 21         public HttpHelper()
 22         {
 23             CookieContainer = new CookieContainer();
 24             Encoding = Encoding.UTF8;
 25         }
 26 
 27         /// <summary>
 28         /// 访问次数字典
 29         /// </summary>
 30         private ConcurrentDictionary<String, int> urlTryList = new ConcurrentDictionary<string, int>();
 31 
 32         /// <summary>
 33         /// Cookie 容器
 34         /// </summary>
 35         public CookieContainer CookieContainer { set; get; }
 36 
 37         /// <summary>
 38         /// Post数据
 39         /// </summary>
 40         public String PostData { set; private get; }
 41 
 42         /// <summary>
 43         /// 页面语言
 44         /// </summary>
 45         public Encoding Encoding { set; private get; }
 46 
 47         /// <summary>
 48         /// 验证码路径
 49         /// </summary>
 50         public string CodePath { get; set; }
 51 
 52         /// <summary>
 53         /// 文件保存路径
 54         /// </summary>
 55         public String FileSavePath { set; private get; }
 56 
 57         /// <summary>
 58         /// 回调时间
 59         /// </summary>
 60         public Action<String, String> CallBackAction;
 61 
 62 
 63         /// <summary>
 64         /// 异步请求
 65         /// </summary>
 66         /// <param name="url">请求地址</param>
 67         /// <param name="tryTimes">错误重试次数</param>
 68         public void AsynRequest(String url, int tryTimes = 3)
 69         {
 70             Trace.TraceInformation(String.Concat("开始异步请求:", url));
 71             urlTryList.TryAdd(url, tryTimes);
 72             var request = WebRequest.Create(url) as HttpWebRequest;
 73             if (request == null) return;
 74             request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
 75             request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
 76             request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate |
 77                                              DecompressionMethods.None;
 78             request.Credentials = CredentialCache.DefaultNetworkCredentials;
 79             request.UseDefaultCredentials = false;
 80             request.KeepAlive = false;
 81             request.PreAuthenticate = false;
 82             request.ProtocolVersion = HttpVersion.Version10;
 83             request.UserAgent =
 84                 "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36";
 85             request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
 86             //request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
 87             request.Timeout = 1000*60*3;
 88             request.CookieContainer = CookieContainer;
 89             //request.AllowAutoRedirect = false;
 90 
 91             if (!String.IsNullOrEmpty(PostData))
 92             {
 93                 request.ContentType = "application/x-www-form-urlencoded";
 94                 request.Method = "POST";
 95                 request.BeginGetRequestStream(GetRequestStreamCallback, request);
 96             }
 97             else
 98             {
 99                 //request.AllowReadStreamBuffering = false;
100                 request.AllowWriteStreamBuffering = false;
101                 request.BeginGetResponse(GetResponseCallback, request);
102             }
103         }
104 
105         /// <summary>
106         /// 开始对用来写入数据的 Stream 对象的异步请求。
107         /// </summary>
108         /// <param name="ar"></param>
109         private void GetRequestStreamCallback(IAsyncResult ar)
110         {
111             var request = ar.AsyncState as HttpWebRequest;
112             if (request == null) return;
113             var postStream = request.EndGetRequestStream(ar);
114             var byteArray = Encoding.GetBytes(PostData);
115             postStream.Write(byteArray, 0, PostData.Length);
116             postStream.Close();
117             request.BeginGetResponse(GetResponseCallback, request);
118         }
119 
120         /// <summary>
121         /// 开始对 Internet 资源的异步请求。 
122         /// </summary>
123         /// <param name="ar"></param>
124         private void GetResponseCallback(IAsyncResult ar)
125         {
126             var request = ar.AsyncState as HttpWebRequest;
127             if (request == null) return;
128             try
129             {
130                 using (var response = request.EndGetResponse(ar) as HttpWebResponse)
131                 {
132                     if (response != null)
133                     {
134                         //if (response.StatusCode == HttpStatusCode.Found)
135                         //{
136                         //    string redirect = response.Headers["Location"];
137                         //    if (!String.IsNullOrEmpty(redirect)) AsynRequest(redirect);
138                         //    return;
139                         //}
140 
141                         if (response.StatusCode != HttpStatusCode.OK)
142                         {
143                             Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败,HttpStatusCode",
144                                 response.StatusCode));
145                             return;
146                         }
147 
148                         using (var streamResponse = response.GetResponseStream())
149                         {
150                             if (streamResponse != null)
151                             {
152                                 if (!IsText(response.ContentType))
153                                 {
154                                     var contentEncodingStr = response.ContentEncoding;
155                                     var contentEncoding = Encoding;
156                                     if (!String.IsNullOrEmpty(contentEncodingStr))
157                                         contentEncoding = Encoding.GetEncoding(contentEncodingStr);
158                                     using (var streamRead = new StreamReader(streamResponse, contentEncoding))
159                                     {
160                                         var str = streamRead.ReadToEnd();
161                                         if (CallBackAction != null && !String.IsNullOrEmpty(str))
162                                             CallBackAction.BeginInvoke(str, request.RequestUri.ToString(), (s) => { },
163                                                 null);
164                                     }
165                                 }
166                                 else
167                                 {
168                                     var fileName = String.Concat(DateTime.Now.ToString("yyyyMMdd"), "/",
169                                         DateTime.Now.ToString("yyyyMMddHHmmssffff"),
170                                         //Extensions.String_.Extensions.GetRnd(6, true, false, false, false, String.Empty),
171                                         ".jpg");
172                                     var fileDirectory = Path.Combine(FileSavePath, DateTime.Now.ToString("yyyyMMdd"));
173                                     CodePath = Path.Combine(FileSavePath, fileName);
174                                     if (!Directory.Exists(fileDirectory))
175                                         Directory.CreateDirectory(fileDirectory);
176 
177                                     //下载文件
178                                     using (
179                                         var fileStream = new FileStream(Path.Combine(FileSavePath, fileName),
180                                             FileMode.Create))
181                                     {
182                                         var buffer = new byte[2048];
183                                         int readLength;
184                                         do
185                                         {
186                                             readLength = streamResponse.Read(buffer, 0, buffer.Length);
187                                             fileStream.Write(buffer, 0, readLength);
188                                         } while (readLength != 0);
189                                     }
190                                     if (CallBackAction != null && !String.IsNullOrEmpty(fileName))
191                                         CallBackAction.BeginInvoke(fileName, request.RequestUri.ToString(), (s) => { },
192                                             null);
193                                 }
194                             }
195                         }
196                         response.Close();
197                     }
198                 }
199             }
200             catch (WebException ex)
201             {
202                 Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败信息:", ex.Message));
203                 var toUrl = request.RequestUri.ToString();
204                 int tryTimes;
205                 if (urlTryList.TryGetValue(toUrl, out tryTimes))
206                 {
207                     urlTryList.TryUpdate(toUrl, tryTimes, tryTimes - 1);
208                     if (tryTimes - 1 <= 0)
209                     {
210                         urlTryList.TryRemove(toUrl, out tryTimes);
211                         return;
212                     }
213                     AsynRequest(toUrl);
214                 }
215             }
216             finally
217             {
218                 request.Abort();
219             }
220         }
221 
222 
223         /// <summary>
224         /// 同步请求
225         /// </summary>
226         /// <param name="url">请求地址</param>
227         /// <param name="tryTimes">错误重试次数</param>
228         public String SyncRequest(String url, int tryTimes = 3)
229         {
230             Trace.TraceInformation(String.Concat("开始同步请求:", url));
231             urlTryList.TryAdd(url, tryTimes);
232             var request = WebRequest.Create(url) as HttpWebRequest;
233             if (request == null) return String.Empty;
234             request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
235             request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
236             request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate |
237                                              DecompressionMethods.None;
238             request.Credentials = CredentialCache.DefaultNetworkCredentials;
239             request.UseDefaultCredentials = false;
240             request.KeepAlive = false;
241             request.PreAuthenticate = false;
242             request.ProtocolVersion = HttpVersion.Version10;
243             request.UserAgent =
244                 "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36";
245             request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
246             request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
247             request.Timeout = 1000*60*3;
248             request.CookieContainer = CookieContainer;
249             request.AllowAutoRedirect = true;
250 
251             if (!String.IsNullOrEmpty(PostData))
252             {
253                 request.ContentType = "application/x-www-form-urlencoded";
254                 request.Method = "POST";
255                 using (var postStream = request.GetRequestStream())
256                 {
257                     var byteArray = Encoding.GetBytes(PostData);
258                     postStream.Write(byteArray, 0, PostData.Length);
259                     postStream.Close();
260                 }
261             }
262             else
263             {
264                 //request.AllowReadStreamBuffering = false;
265                 request.AllowWriteStreamBuffering = false;
266             }
267             try
268             {
269                 using (var response = request.GetResponse() as HttpWebResponse)
270                 {
271                     if (response != null)
272                     {
273                         if (response.StatusCode != HttpStatusCode.OK)
274                         {
275                             Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败,HttpStatusCode",
276                                 response.StatusCode));
277                             return String.Empty;
278                         }
279                         using (var streamResponse = response.GetResponseStream())
280                         {
281                             if (streamResponse != null)
282                             {
283                                 if (!IsText(response.ContentType))
284                                 {
285                                     var contentEncodingStr = response.ContentEncoding;
286                                     var contentEncoding = Encoding;
287                                     if (!String.IsNullOrEmpty(contentEncodingStr))
288                                         contentEncoding = Encoding.GetEncoding(contentEncodingStr);
289                                     var streamRead = new StreamReader(streamResponse, contentEncoding);
290                                     var str = streamRead.ReadToEnd();
291                                     if (CallBackAction != null && !String.IsNullOrEmpty(str))
292                                         CallBackAction.BeginInvoke(str, request.RequestUri.ToString(), (s) => { }, null);
293                                     return str;
294                                 }
295 
296                                 var fileName = String.Concat(DateTime.Now.ToString("yyyyMMdd"), "/",
297                                     DateTime.Now.ToString("yyyyMMddHHmmssffff"),
298                                     //Extensions.String_.Extensions.GetRnd(6, true, false, false, false, String.Empty),
299                                     Path.GetExtension(request.RequestUri.AbsoluteUri));
300                                 var fileDirectory = Path.Combine(FileSavePath, DateTime.Now.ToString("yyyyMMdd"));
301                                 if (!Directory.Exists(fileDirectory))
302                                     Directory.CreateDirectory(fileDirectory);
303 
304                                 //下载文件
305                                 using (
306                                     var fileStream = new FileStream(Path.Combine(FileSavePath, fileName),
307                                         FileMode.Create))
308                                 {
309                                     var buffer = new byte[2048];
310                                     int readLength;
311                                     do
312                                     {
313                                         readLength = streamResponse.Read(buffer, 0, buffer.Length);
314                                         fileStream.Write(buffer, 0, readLength);
315                                     } while (readLength != 0);
316                                 }
317                                 if (CallBackAction != null && !String.IsNullOrEmpty(fileName))
318                                     CallBackAction.BeginInvoke(fileName, request.RequestUri.ToString(), (s) => { }, null);
319                                 return fileName;
320                             }
321                         }
322                         response.Close();
323                     }
324                 }
325             }
326             catch (WebException ex)
327             {
328                 Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败信息:", ex.Message));
329                 var toUrl = request.RequestUri.ToString();
330                 if (urlTryList.TryGetValue(toUrl, out tryTimes))
331                 {
332                     urlTryList.TryUpdate(toUrl, tryTimes, tryTimes - 1);
333                     if (tryTimes - 1 <= 0)
334                     {
335                         urlTryList.TryRemove(toUrl, out tryTimes);
336                         Trace.TraceError(String.Concat("请求地址重试失败:", request.RequestUri));
337                         return String.Empty;
338                     }
339                     SyncRequest(toUrl);
340                 }
341             }
342             finally
343             {
344                 request.Abort();
345             }
346             return String.Empty;
347         }
348 
349         /// <summary>
350         /// 验证码获取
351         /// </summary>
352         /// <param name="url">请求地址</param>
353         /// <param name="tryTimes">错误重试次数</param>
354         public Bitmap GetCheckCode(String url, int tryTimes = 3)
355         {
356             Trace.TraceInformation(String.Concat("开始同步请求:", url));
357             urlTryList.TryAdd(url, tryTimes);
358             var request = WebRequest.Create(url) as HttpWebRequest;
359             if (request == null) return null;
360             request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
361             request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
362             request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate |
363                                              DecompressionMethods.None;
364             request.Credentials = CredentialCache.DefaultNetworkCredentials;
365             request.UseDefaultCredentials = false;
366             request.KeepAlive = false;
367             request.PreAuthenticate = false;
368             request.ProtocolVersion = HttpVersion.Version10;
369             request.UserAgent =
370                 "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36";
371             request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
372             request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
373             request.Timeout = 1000*60*3;
374             request.CookieContainer = CookieContainer;
375             request.AllowAutoRedirect = true;
376 
377             if (!String.IsNullOrEmpty(PostData))
378             {
379                 request.ContentType = "application/x-www-form-urlencoded";
380                 request.Method = "POST";
381                 using (var postStream = request.GetRequestStream())
382                 {
383                     var byteArray = Encoding.GetBytes(PostData);
384                     postStream.Write(byteArray, 0, PostData.Length);
385                     postStream.Close();
386                 }
387             }
388             else
389             {
390                 //request.AllowReadStreamBuffering = false;
391                 request.AllowWriteStreamBuffering = false;
392             }
393             try
394             {
395                 using (var response = request.GetResponse() as HttpWebResponse)
396                 {
397                     if (response != null)
398                     {
399                         if (response.StatusCode != HttpStatusCode.OK)
400                         {
401                             Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败,HttpStatusCode",
402                                 response.StatusCode));
403                             return null;
404                         }
405                         using (var streamResponse = response.GetResponseStream())
406                         {
407                             if (streamResponse != null)
408                             {
409                                 return (Bitmap) Bitmap.FromStream(streamResponse);
410                             }
411                         }
412                         response.Close();
413                     }
414                 }
415             }
416             catch (WebException ex)
417             {
418                 Trace.TraceError(String.Concat("请求地址:", request.RequestUri, " 失败信息:", ex.Message));
419                 var toUrl = request.RequestUri.ToString();
420                 if (urlTryList.TryGetValue(toUrl, out tryTimes))
421                 {
422                     urlTryList.TryUpdate(toUrl, tryTimes, tryTimes - 1);
423                     if (tryTimes - 1 <= 0)
424                     {
425                         urlTryList.TryRemove(toUrl, out tryTimes);
426                         Trace.TraceError(String.Concat("请求地址重试失败:", request.RequestUri));
427                         return null;
428                     }
429                     GetCheckCode(toUrl);
430                 }
431             }
432             finally
433             {
434                 request.Abort();
435             }
436             return null;
437         }
438 
439         /// <summary>
440         /// 判断文件是否为文本类型
441         /// </summary>
442         /// <param name="contentType">内容类型</param>
443         /// <returns></returns>
444         private static bool IsText(String contentType)
445         {
446             var fileContentType = new List<string>
447             {
448                 "image/Bmp",
449                 "image/gif",
450                 "image/jpeg",
451                 "image/png",
452                 "image/tiff",
453                 "application/octet-stream"
454             };
455             return fileContentType.Contains(contentType);
456         }
457     }
458 }
HttpHepler
技术分享
  1 using System;
  2 using System.Drawing;
  3 using System.Drawing.Drawing2D;
  4 using System.Drawing.Imaging;
  5 using System.Runtime.InteropServices;
  6 
  7 namespace Tesseract.Test.Tools
  8 {
  9     public class UnCodebase
 10     {
 11         public Bitmap bmpobj;
 12 
 13         public UnCodebase(Bitmap pic)
 14         {
 15             bmpobj = new Bitmap(pic); //转换为Format32bppRgb
 16         }
 17 
 18         /// <summary>
 19         /// 根据RGB,计算灰度值
 20         /// </summary>
 21         /// <param name="posClr">Color值</param>
 22         /// <returns>灰度值,整型</returns>
 23         private int GetGrayNumColor(Color posClr)
 24         {
 25             return (posClr.R*19595 + posClr.G*38469 + posClr.B*7472) >> 16;
 26         }
 27 
 28         /// <summary>
 29         /// 灰度转换,逐点方式
 30         /// </summary>
 31         public Bitmap GrayByPixels()
 32         {
 33             for (int i = 0; i < bmpobj.Height; i++)
 34             {
 35                 for (int j = 0; j < bmpobj.Width; j++)
 36                 {
 37                     int tmpValue = GetGrayNumColor(bmpobj.GetPixel(j, i));
 38                     bmpobj.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));
 39                 }
 40             }
 41             return bmpobj;
 42         }
 43 
 44         /// <summary>
 45         /// 去图形边框
 46         /// </summary>
 47         /// <param name="borderWidth"></param>
 48         public Bitmap ClearPicBorder(int borderWidth)
 49         {
 50             for (int i = 0; i < bmpobj.Height; i++)
 51             {
 52                 for (int j = 0; j < bmpobj.Width; j++)
 53                 {
 54                     if (i < borderWidth || j < borderWidth || j > bmpobj.Width - 1 - borderWidth ||
 55                         i > bmpobj.Height - 1 - borderWidth)
 56                         bmpobj.SetPixel(j, i, Color.FromArgb(255, 255, 255));
 57                 }
 58             }
 59             return bmpobj;
 60         }
 61 
 62         /// <summary>
 63         /// 灰度转换,逐行方式
 64         /// </summary>
 65         public Bitmap GrayByLine()
 66         {
 67             Rectangle rec = new Rectangle(0, 0, bmpobj.Width, bmpobj.Height);
 68             BitmapData bmpData = bmpobj.LockBits(rec, ImageLockMode.ReadWrite, bmpobj.PixelFormat);
 69             // PixelFormat.Format32bppPArgb);
 70             //    bmpData.PixelFormat = PixelFormat.Format24bppRgb;
 71             IntPtr scan0 = bmpData.Scan0;
 72             int len = bmpobj.Width*bmpobj.Height;
 73             int[] pixels = new int[len];
 74             Marshal.Copy(scan0, pixels, 0, len);
 75 
 76             //对图片进行处理
 77             int GrayValue = 0;
 78             for (int i = 0; i < len; i++)
 79             {
 80                 GrayValue = GetGrayNumColor(Color.FromArgb(pixels[i]));
 81                 pixels[i] = (byte) (Color.FromArgb(GrayValue, GrayValue, GrayValue)).ToArgb(); //Color转byte
 82             }
 83 
 84             bmpobj.UnlockBits(bmpData);
 85             return bmpobj;
 86         }
 87 
 88         /// <summary>
 89         /// 得到有效图形并调整为可平均分割的大小
 90         /// </summary>
 91         /// <param name="dgGrayValue">灰度背景分界值</param>
 92         /// <param name="CharsCount">有效字符数</param>
 93         /// <returns></returns>
 94         public void GetPicValidByValue(int dgGrayValue, int CharsCount)
 95         {
 96             int posx1 = bmpobj.Width;
 97             int posy1 = bmpobj.Height;
 98             int posx2 = 0;
 99             int posy2 = 0;
100             for (int i = 0; i < bmpobj.Height; i++) //找有效区
101             {
102                 for (int j = 0; j < bmpobj.Width; j++)
103                 {
104                     int pixelValue = bmpobj.GetPixel(j, i).R;
105                     if (pixelValue < dgGrayValue) //根据灰度值
106                     {
107                         if (posx1 > j) posx1 = j;
108                         if (posy1 > i) posy1 = i;
109 
110                         if (posx2 < j) posx2 = j;
111                         if (posy2 < i) posy2 = i;
112                     }
113                     ;
114                 }
115                 ;
116             }
117             ;
118             // 确保能整除
119             int Span = CharsCount - (posx2 - posx1 + 1)%CharsCount; //可整除的差额数
120             if (Span < CharsCount)
121             {
122                 int leftSpan = Span/2; //分配到左边的空列 ,如span为单数,则右边比左边大1
123                 if (posx1 > leftSpan)
124                     posx1 = posx1 - leftSpan;
125                 if (posx2 + Span - leftSpan < bmpobj.Width)
126                     posx2 = posx2 + Span - leftSpan;
127             }
128             //复制新图
129             Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
130             bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
131         }
132 
133         /// <summary>
134         /// 得到有效图形,图形为类变量
135         /// </summary>
136         /// <param name="dgGrayValue">灰度背景分界值</param>
137         /// <param name="CharsCount">有效字符数</param>
138         /// <returns></returns>
139         public void GetPicValidByValue(int dgGrayValue)
140         {
141             int posx1 = bmpobj.Width;
142             int posy1 = bmpobj.Height;
143             int posx2 = 0;
144             int posy2 = 0;
145             for (int i = 0; i < bmpobj.Height; i++) //找有效区
146             {
147                 for (int j = 0; j < bmpobj.Width; j++)
148                 {
149                     int pixelValue = bmpobj.GetPixel(j, i).R;
150                     if (pixelValue < dgGrayValue) //根据灰度值
151                     {
152                         if (posx1 > j) posx1 = j;
153                         if (posy1 > i) posy1 = i;
154 
155                         if (posx2 < j) posx2 = j;
156                         if (posy2 < i) posy2 = i;
157                     }
158                     ;
159                 }
160                 ;
161             }
162             ;
163             //复制新图
164             Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
165             bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
166         }
167 
168         /// <summary>
169         /// 得到有效图形,图形由外面传入
170         /// </summary>
171         /// <param name="dgGrayValue">灰度背景分界值</param>
172         /// <param name="CharsCount">有效字符数</param>
173         /// <returns></returns>
174         public Bitmap GetPicValidByValue(Bitmap singlepic, int dgGrayValue)
175         {
176             int posx1 = singlepic.Width;
177             int posy1 = singlepic.Height;
178             int posx2 = 0;
179             int posy2 = 0;
180             for (int i = 0; i < singlepic.Height; i++) //找有效区
181             {
182                 for (int j = 0; j < singlepic.Width; j++)
183                 {
184                     int pixelValue = singlepic.GetPixel(j, i).R;
185                     if (pixelValue < dgGrayValue) //根据灰度值
186                     {
187                         if (posx1 > j) posx1 = j;
188                         if (posy1 > i) posy1 = i;
189 
190                         if (posx2 < j) posx2 = j;
191                         if (posy2 < i) posy2 = i;
192                     }
193                     ;
194                 }
195                 ;
196             }
197             ;
198             //复制新图
199             Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
200             return singlepic.Clone(cloneRect, singlepic.PixelFormat);
201         }
202 
203         /// <summary>
204         /// 平均分割图片
205         /// </summary>
206         /// <param name="RowNum">水平上分割数</param>
207         /// <param name="ColNum">垂直上分割数</param>
208         /// <returns>分割好的图片数组</returns>
209         public Bitmap[] GetSplitPics(int RowNum, int ColNum)
210         {
211             if (RowNum == 0 || ColNum == 0)
212                 return null;
213             int singW = bmpobj.Width/RowNum;
214             int singH = bmpobj.Height/ColNum;
215             Bitmap[] PicArray = new Bitmap[RowNum*ColNum];
216 
217             Rectangle cloneRect;
218             for (int i = 0; i < ColNum; i++) //找有效区
219             {
220                 for (int j = 0; j < RowNum; j++)
221                 {
222                     cloneRect = new Rectangle(j*singW, i*singH, singW, singH);
223                     PicArray[i*RowNum + j] = bmpobj.Clone(cloneRect, bmpobj.PixelFormat); //复制小块图
224                 }
225             }
226             return PicArray;
227         }
228 
229         /// <summary>
230         /// 返回灰度图片的点阵描述字串,1表示灰点,0表示背景
231         /// </summary>
232         /// <param name="singlepic">灰度图</param>
233         /// <param name="dgGrayValue">背前景灰色界限</param>
234         /// <returns></returns>
235         public string GetSingleBmpCode(Bitmap singlepic, int dgGrayValue)
236         {
237             Color piexl;
238             string code = "";
239             for (int posy = 0; posy < singlepic.Height; posy++)
240                 for (int posx = 0; posx < singlepic.Width; posx++)
241                 {
242                     piexl = singlepic.GetPixel(posx, posy);
243                     if (piexl.R < dgGrayValue) // Color.Black )
244                         code = code + "1";
245                     else
246                         code = code + "0";
247                 }
248             return code;
249         }
250 
251         /// <summary>
252         /// 去掉噪点
253         /// </summary>
254         /// <param name="dgGrayValue"></param>
255         /// <param name="MaxNearPoints"></param>
256         public Bitmap ClearNoise(int dgGrayValue, int MaxNearPoints)
257         {
258             Color piexl;
259             int nearDots = 0;
260             int XSpan, YSpan, tmpX, tmpY;
261             //逐点判断
262             for (int i = 0; i < bmpobj.Width; i++)
263                 for (int j = 0; j < bmpobj.Height; j++)
264                 {
265                     piexl = bmpobj.GetPixel(i, j);
266                     if (piexl.R < dgGrayValue)
267                     {
268                         nearDots = 0;
269                         //判断周围8个点是否全为空
270                         if (i == 0 || i == bmpobj.Width - 1 || j == 0 || j == bmpobj.Height - 1) //边框全去掉
271                         {
272                             bmpobj.SetPixel(i, j, Color.FromArgb(255, 255, 255));
273                         }
274                         else
275                         {
276                             if (bmpobj.GetPixel(i - 1, j - 1).R < dgGrayValue) nearDots++;
277                             if (bmpobj.GetPixel(i, j - 1).R < dgGrayValue) nearDots++;
278                             if (bmpobj.GetPixel(i + 1, j - 1).R < dgGrayValue) nearDots++;
279                             if (bmpobj.GetPixel(i - 1, j).R < dgGrayValue) nearDots++;
280                             if (bmpobj.GetPixel(i + 1, j).R < dgGrayValue) nearDots++;
281                             if (bmpobj.GetPixel(i - 1, j + 1).R < dgGrayValue) nearDots++;
282                             if (bmpobj.GetPixel(i, j + 1).R < dgGrayValue) nearDots++;
283                             if (bmpobj.GetPixel(i + 1, j + 1).R < dgGrayValue) nearDots++;
284                         }
285 
286                         if (nearDots < MaxNearPoints)
287                             bmpobj.SetPixel(i, j, Color.FromArgb(255, 255, 255)); //去掉单点 && 粗细小3邻边点
288                     }
289                     else //背景
290                         bmpobj.SetPixel(i, j, Color.FromArgb(255, 255, 255));
291                 }
292             return bmpobj;
293         }
294 
295         /// <summary>
296         /// 扭曲图片校正
297         /// </summary>
298         public Bitmap ReSetBitMap()
299         {
300             Graphics g = Graphics.FromImage(bmpobj);
301             Matrix X = new Matrix();
302             //  X.Rotate(30);
303             X.Shear((float) 0.16666666667, 0); //  2/12
304             g.Transform = X;
305             // Draw image
306             //Rectangle cloneRect = GetPicValidByValue(128);  //Get Valid Pic Rectangle
307             Rectangle cloneRect = new Rectangle(0, 0, bmpobj.Width, bmpobj.Height);
308             Bitmap tmpBmp = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
309             g.DrawImage(tmpBmp,
310                 new Rectangle(0, 0, bmpobj.Width, bmpobj.Height),
311                 0, 0, tmpBmp.Width,
312                 tmpBmp.Height,
313                 GraphicsUnit.Pixel);
314 
315             return tmpBmp;
316         }
317     }
318 }
UnCodebase
技术分享
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using Tesseract.Test.Tools;
 7 
 8 namespace Tesseract.Test
 9 {
10     /// <summary>
11     /// 网站用户
12     /// </summary>
13     public class WebUser
14     {
15         /// <summary>
16         /// 用户名
17         /// </summary>
18         private string _userName = string.Empty;
19 
20         /// <summary>
21         /// 密码
22         /// </summary>
23         private string _password = string.Empty;
24 
25         /// <summary>
26         /// 验证码
27         /// </summary>
28         private string _checkCode = string.Empty;
29 
30         private HttpHelper _httpHelper = new HttpHelper();
31 
32         /// <summary>
33         /// 构造函数
34         /// </summary>
35         public WebUser()
36         {
37             _userName = "admin"; //初始化用户
38             _password = "password"; //初始化密码
39             Login();
40         }
41 
42 
43         /// <summary>
44         /// 登录
45         /// </summary>
46         private void Login()
47         {
48             //登录页
49             _httpHelper.SyncRequest("Login.html");
50 
51             //获取验证码图片
52             var bitmap = _httpHelper.GetCheckCode("CheckCode.html");
53 
54             //解析验证码
55             using (var engine = new TesseractEngine(@"./tessdata", "eng", EngineMode.Default))
56             {
57                 using (var entity = engine.Process(bitmap))
58                 {
59                     _checkCode = entity.GetText();
60                 }
61             }
62 
63             //登录验证
64             _httpHelper.PostData = string.Format("userName={0}&password={1}&checkcode={2}",
65                 _userName, _password, _checkCode);
66             _httpHelper.SyncRequest("CheckLogin.html");
67         }
68     }
69 }
WebUser

四、代码解释

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

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

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

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

5、登录成功。

 

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

标签:

原文地址:http://www.cnblogs.com/JinJi-Jary/p/5625414.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!