zoukankan      html  css  js  c++  java
  • webbrowser取页面验证码

    碰到一个无比坑爹,外加蛋疼乳酸的问题。从昨天晚上发现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[0].Document.DomDocument).body;
    IHTMLControlElement img = (IHTMLControlElement)((mshtml.HTMLDocumentClass)wbsContent.Document.Window.Frames[0].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[0].Document.DomDocument).all.item("code");
        txtVrf.setAttribute("value", code);
        return true;
    }

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

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

  • 相关阅读:
    tidb3.2参数优化配置整个过程
    tidb优化配置
    mysql使用docker安装
    mysql密码规则配置-配置为简单密码123456
    goaccess日志分析器使用
    c# printDialog不显示问题
    short数组写进txt
    txt文件存储问题
    c# 调用c++dll二次总结
    程序员代码开发的自测素养
  • 原文地址:https://www.cnblogs.com/icyJ/p/webbrowser.html
Copyright © 2011-2022 走看看