百度贴吧的验证码是通过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接口也是第一次使用,用的比较糟烂
转载于:https://www.cnblogs.com/steden/archive/2012/11/28/2792315.html