使用C#开发百度空间验证码自动填写的工具

百度贴吧的验证码是通过js调用的,好像有点ajax的意思,具体没有搞太明白。
当我们的光标焦点在了回复编辑框时,触发了一个onfocus事件,onfocus事件的脚本将验证码的输入框的display属性改为true,之后当我们将光标移动到验证码输入框之后又触发了一个onfocus事件,同时js脚本将验证码现实出来。 看完这个之后整个过程也就基本明了了,我们要想自动识别验证码并填写,首先我们要将现实验证码的图片或得了。 那么或得这个图片之前我们肯定要显示这个图片,也就是必须模拟出以上步骤,光标聚焦的回复编辑框的事件我们不用来处理,因为我们要恢复肯定要填写一定内容,但是下面的步骤就必须要模拟一下了。因为我们是在外部来访问ie浏览器,我们使用mshtml.dl。
首先在你的项目内引用mshtml.dll
using mshtml;
在类之前加入下面代码,将com的交互访问设置为true
[System.Runtime.InteropServices.ComVisible(true)]
    
然后我们定义一个获取图片的方法getimage,getimage通过mshtml的ihtml接口访问ie内的html元素
         private Bitmap getImage()
         {
             mshtml.IHTMLDocument2 Doc;
             mshtml.IHTMLElement element;
             mshtml.IHTMLElementCollection all;
             SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindowsClass();
             string filename;
             Bitmap Img=null;
//便利进程树,从中找到浏览器
             foreach (SHDocVw.InternetExplorer ie in shellWindows)
             {
                 filename = Path.GetFileNameWithoutExtension(ie.FullName).ToLower();
                 if (filename.Equals(“iexplore”)) //如果进程名为iexplore
                 {
                   
                     Doc = ie.Document as mshtml.IHTMLDocument2;
                     mshtml.IHTMLControlElement item;
                     HTMLBody body = (HTMLBody)Doc.body;
                     mshtml.IHTMLControlRange range = (IHTMLControlRange)body.createControlRange();
                     if (Doc.domain == “baidu.com”)
                     {
                     
                        all = Doc.all;                     
                         element = all.item(“captcha”, null) as mshtml.IHTMLElement;
                         element.click(); .//模拟鼠标点击动作
                        System.Threading.Thread.Sleep(1000); //暂停1秒等ie响应
                         item = all.item(“captcha_img”, null) as mshtml.IHTMLControlElement;
                         System.Threading.Thread.Sleep(1000);//等待ie读取验证码图片
                         range.add(item);
                         range.execCommand(“Copy”, false, null);
                         Img =new Bitmap(Clipboard.GetImage()); //从剪切板中获取验证码图片
                         Clipboard.Clear();
                     }
                 }
             }
             return Img;
         }
现在我们已经获取了一个图像文件,接下来我们需要做的就是图像的识别工作了,图像识别这里我们使用谷歌公司的开源库Tesseract 来完成,先介绍一下Tesseract 。
这款名为Tesseract的OCR引擎最先由HP实验室于1985年开始研发,至1995年时已经成为OCR业内最准确的三款识别引擎之一。然而,HP不久便决定放弃OCR业务,Tesseract也从从此尘封。
数年以后,HP意识到,与其将Tesseract束之高阁,不如贡献给开源软件业,让其重焕新生--2005年,Tesseract由美国内华达州信息技术研究所获得,并求诸于Google对Tesseract进行改进、消除Bug、优化工作。
在修复了最重要的数个漏洞后,Google认为Tesseract OCR已经足够稳定,可以重新以开源软件方式发布。
http://sourceforge.net/projects/tesseract-ocr
我们使用的是Tesseract的.net版本,大家可以到http://www.pixel-technology.com/freeware/tessnet2/下载
接下来我们来做一下识别验证码的方法
         private void Ocr()
         {
          string datapath = System.Environment.CurrentDirectory + “\\tessdata“; //这个是必须的,我们的字库信息就存储在这里
            tessnet2.Tesseract ocr = new tessnet2.Tesseract();
            ocr.Init(datapath, “eng”, false);
            ocr.OcrDone = new tessnet2.Tesseract.OcrDoneHandler(Done);//使用一个Handler接管完成识别后的操作
            ocr.DoOCR(getImage(), Rectangle.Empty);
          }
void Done((List<tessnet2.Word> Words){
str = Words[0]; //这里的str是全局的。
}
验证码识别出来了,接下来我们把它填入验证码输入框中
public void write()
        {
            mshtml.IHTMLDocument2 Doc;
            mshtml.IHTMLElement element;
            mshtml.IHTMLElementCollection all;
            SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindowsClass();
            string filename;
            Bitmap Img = null;
            foreach (SHDocVw.InternetExplorer ie in shellWindows)
            {
                filename = Path.GetFileNameWithoutExtension(ie.FullName).ToLower();
                if (filename.Equals(“iexplore”))
                {
                    Doc = ie.Document as mshtml.IHTMLDocument2;
               
                    HTMLBody body = (HTMLBody)Doc.body;
                    mshtml.IHTMLControlRange range = (IHTMLControlRange)body.createControlRange();
                    if (Doc.domain == “baidu.com”)
                    {
                        all = Doc.all;
                     
                        element= all.item(“captcha”, null) as mshtml.IHTMLElement;
                     
                        element.setAttribute(“Value”, str, 0);
                    }
                }
            }
        }
这个程序基本上也算是完成了,试验中边度的验证码识别率大约在40%左右,也就是说有一半的验证码还是识别不出来,两种可能,一是我没有完全理解Tesseract的使用方法,二是百度的验证码两个字符之间有些交叉的地方,人眼有时都需要仔细分辨才能看清楚,我之前试验用Tesseract识别英文和数字,对于标准的的识别率能达到100%。 好了就说到这里的,如果哪位对Tesseract比较熟悉不妨帮我完善一下这个烂程序。 还有就是ihtml接口也是第一次使用,用的比较糟烂

posted @ 2012-11-28 12:18  steden  阅读(495)  评论(1编辑  收藏  举报