碰到一个无比坑爹,外加蛋疼乳酸的问题。从昨天晚上发现bug,到今天下午解决问题,搞了大半天的时间。光是找问题就花了半天,解决问题的方法简单,但是方案的形成也是无比纠结的过程。

背景:webbrowser获取页面上的验证码,然后解析验证码回写到页面。解析和回写没什么问题,问题主要在获取页面验证码上。

在网上搜索得到这么一段代码:

IHTMLControlElement img = (IHTMLControlElement)webBrowser1.Document.Images["vcode_img"].DomElement;
IHTMLControlRange range = (IHTMLControlRange)((HTMLBody)html.body).createControlRange();
range.add(img);
range.execCommand("Copy", false, null);
img = null;
range = null;
html = null;
if (Clipboard.ContainsImage())
this.pictureBox1.Image = Clipboard.GetImage();
else
MessageBox.Show("执行不成功");
Clipboard.Clear();

获取验证码图片的核心也在这里。复制图片数据到内存,然后从剪贴板读取到pictureBox控件。

图片很顺利的取出来了。

但是实际调用的时候,发现“时灵时不灵”,不时的会冒出“执行不成功”的弹框。

刚开始以为是线程运行顺序导致的,加了一堆Thread.Sleep,发现毫无改善。

各种测试,毫无头绪......

无意中发现某一次报错时,页面上选中了部分文字。难道是这里的问题?于是重点测试,每次选中文字之后,解析验证码,报错。而没有选中文字时,运行这部分代码,安然通过。我X,这是什么狗血情况,问题居然出在页面当前有选中文字上??郁闷呐》。。。。。

找到问题后,解决问题的方向就很明确了。在执行这段代码之前,取消页面选择。

问题又来了,对于我这么一个没搞过js、html的c#初级猿,怎么取消webbrowser页面选择文字还真是难到我了,试过很多方法,focus,select,moveStart,move...通通滴死啦死啦滴...

过程很坎坷,结果很简洁。一句txtRange.execCommand("Unselect");搞定。

完整代码:

var code = "";
var body = (mshtml.HTMLBodyClass)((mshtml.HTMLDocumentClass)wbsContent.Document.Window.Frames[].Document.DomDocument).body;
IHTMLControlElement img = (IHTMLControlElement)((mshtml.HTMLDocumentClass)wbsContent.Document.Window.Frames[].Document.DomDocument).images.item("imgCode");
IHTMLControlRange range = (IHTMLControlRange)body.createControlRange();
IHTMLTxtRange txtRange = body.createTextRange();
txtRange.execCommand("Unselect");
range.add(img);
range.execCommand("Copy");
img = null;
range = null; if (Clipboard.ContainsImage())
{
code = UnCodeBase.GetVarifyCodeFromWinWinTask((Bitmap)Clipboard.GetImage());
var txtVrf = (mshtml.HTMLInputElementClass)((mshtml.HTMLDocumentClass)wbsContent.Document.Window.Frames[].Document.DomDocument).all.item("code");
txtVrf.setAttribute("value", code);
return true;
}

这是Frame的情况,相信没有Frame的情况应该可以照着这个思路处理。

问题解决了的时候,还是很开心的,虽然还是觉得这个问题很让人郁闷.

webbrowser取页面验证码的更多相关文章

  1. 【java】使用URL和CookieManager爬取页面的验证码和cookie并保存

    使用java的net包和io包下的几个工具爬取页面的验证码图片并保存到本地. 然后可以把获取的cookie保存下来,做进一步处理.比如通过识别验证码,进一步使用验证码和用户名,密码,保存下来的cook ...

  2. web页面 验证码 生成

    web页面 验证码 生成 kaptcha 是一个非常实用的验证码生成工具.有了它,你可以生成各种样式的验证码,因为它是可配置的.kaptcha工作的原理是调用 com.google.code.kapt ...

  3. Java爬虫系列二:使用HttpClient抓取页面HTML

    爬虫要想爬取需要的信息,首先第一步就要抓取到页面html内容,然后对html进行分析,获取想要的内容.上一篇随笔<Java爬虫系列一:写在开始前>中提到了HttpClient可以抓取页面内 ...

  4. 【C#】无损转换Image为Icon 【C#】组件发布:MessageTip,轻快型消息提示窗 【C#】给无窗口的进程发送消息 【手记】WebBrowser响应页面中的blank开新窗口及window.close关闭本窗体 【手记】调用Process.EnterDebugMode引发异常:并非所有引用的特权或组都分配给呼叫方 【C#】DataRowState演变备忘

    [C#]无损转换Image为Icon 如题,市面上常见的方法是: var handle = bmp.GetHicon(); //得到图标句柄 return Icon.FromHandle(handle ...

  5. 用PHP抓取页面并分析

    在做抓取前,记得把php.ini中的max_execution_time设置的大点,不然会报错的.

  6. 使用PHP的正则抓取页面中的网址

    最近有一个任务,从页面中抓取页面中所有的链接,当然使用PHP正则表达式是最方便的办法.要写出正则表达式,就要先总结出模式,那么页面中的链接会有几种形式呢?   链接也就是超级链接,是从一个元素(文字. ...

  7. php抓取页面的几种方式

    在做一些天气预报或者RSS订阅的程序时,往往 需要抓取非本地文件,一般情况下都是利用php模拟浏览器的访问,通过http请求访问url地址, 然后得到html源代码或者xml数据,得到数据我们不能直接 ...

  8. Selenium2学习-034-WebUI自动化实战实例-032-获取页面 body 大小

    获取 body 元素大小的方法,非常简单,直接上码,敬请参阅! /** * Get body size * * @author Aaron.ffp * @version V1.0.0: autoSel ...

  9. Selenium2学习-028-WebUI自动化实战实例-026-获取页面元素值或者元素属性值

    在自动化脚本编写过程中,经常需要获取页面元素的文本进行判断,以便对于不同的文本进行不同的处理.比如:很多的购物网站,加入购物车的按钮是有多个状态的(加入购物车.到货通知.暂不销售等),那么在实际的操作 ...

随机推荐

  1. Java 8 Lambda排序 : Comparator example

    1. Classic Comparator example. Comparator<Developer> byName = new Comparator<Developer>( ...

  2. 交叉验证(CrossValidation)方法思想简介[zz]

    以下简称交叉验证(Cross Validation)为CV.CV是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train se ...

  3. 【剑道】日常练习相关Q&A 整理

    Q:如何使手腕灵活,手指灵活.有力量? A: 1)提重物.将手腕搁在膝盖上,凭手指和手腕的力量将重物提上来 2)指卧撑.用十个指头着地的方法做俯卧撑 Q:怎样才算肩膀放松,如何方式? A:收放自如,多 ...

  4. php分享二十三:字符编码

    1:ASCII 在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a.b.c.d这样的52个字母(包括大写).以及0.1等数字还有一些常用的 ...

  5. Linux内核设计基础(一)之中断处理

    假设让内核定期对设备进行轮询.以便处理设备,那会做非常多无用功,假设能让设备在须要内核时主动通知内核,会是一个聪明的方式,这便是中断. 在响应一个特定中断时,内核会运行一个函数--中断处理程序. 中断 ...

  6. git 生成ssh keys

    最近从svn转到gitlab 记录一下如何生成ssh keys 首先下载GitExtensions246SetupComplete.msi并安装,如果已经安装了git,那么安装途中就跳过就行 安装完毕 ...

  7. asp.net core在linux上的部署调试

    双十一买了阿里云的LINUX服务器三年¥720 把自己的niunan.net一系列网站都部署上去 用jexus来部署,部署时发现头一个网站没问题,但是后一个网站部署就有问题..输入域名打不开,但JEX ...

  8. PCIE协议解析 synopsys IP loopback 读书笔记(1)

    1      Overview Core支持单个Pcie内核的Loopback功能,该功能主要为了做芯片验证,以及在没有远程接收器件的情况下完成自己的回环.同时,Core也支持有远程接收器件的loop ...

  9. FFmpeg(13)-创建OpenSLES混音器CreateOutputMix初始化

    一.包含头文件和库文件 CMakeLists target_link_libraries( # Specifies the target library. native-lib OpenSLES # ...

  10. update set where exists 多表更新 在mssql、MySQL、Oracle中分别用法

    MySQL: UPDATE ChgCfm t1 INNER JOIN tb_dz_file t2 ON t1.ID = t2.ID ' SQLserver: FROM ChgCfmRcd t1 ' F ...