WebBrowser与mshtml获取动态验证码
动态验证码:同一个链接,但每次请求都得到不同图片的验证码。我们可以通过WebBrowser与mshtml结合的方式来获取动态验证码,可以确保我们获取到本地的验证码图片与第一次请求该验证码所在网页中的图片一致。
本文以NydusVPN的登录页面为例来说明我尝试过的获取动态验证码的方法,该网站可以通过签到和推广获取VPN的免费使用时间,我的推广链接:NydusVPN。
1.HttpHelper获取动态验证码
这个方法是从苏飞论坛上学来的,方法概要:首先请求NydusVPN的登录页面,获取Cookie和动态验证码链接;然后带着Cookie发出第二次请求,并将返回的验证码图片显示在我们指定的位置,第二次请求的是第一次获取的动态验证码链接。
事实上,第二次请求得到的验证码与我们第一次请求时页面加载的验证码是不一样的,如果按照第二次获取的验证码去提交登录请求,是不能成功的,我觉得登录不成功的原因应该是验证码不正确。不过这种方法用于获取非动态的验证码应该是没有问题的。
针对这个问题点,我在苏飞论坛上有发帖求助,苏飞站长也进行了回复,但目前还并没有实质性的进展,有兴趣的同学可以去围观,求助帖的地址:http://www.sufeinet.com/thread-13273-1-1.html。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
private void GetVerCode() { /* 原网站中验证码图片的HTML * <img src="/code?d=745090" id="codeimg" alt="验证码" style="vertical-align:top;cursor:pointer;margin-top:padding-bottom:10px;" * title="点击刷新验证码" onclick="this.src='/code?d='+Math.random();"> */ //这里第一次请求链接时就会加载一张验证码 item = new HttpItem() { URL = "http://www.nydus2015.info/login?callback=/loginbbs", Method = "GET", Accept = "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*", UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)" }; result = http.GetHtml(item); Cookies = result.Cookie; retCode = result.Html; //虽然这里获取了验证码的链接,但用同样的链接再次提交时,就会加载另一张验证码 //用第二次提交得到的验证码去登录时不会成功的 dCode = Utilities.GetMidStr(retCode, @"code?d=", "\""); item = new HttpItem() { URL = "http://www.nydus2015.info/code?d=" + dCode, Method = "GET", Accept = "*/*", Referer = "http://www.nydus2015.info/", ResultType = ResultType.Byte, Cookie = Cookies }; result = http.GetHtml(item); pictureBox1.Image = Utilities.GetImageFromByte(result.ResultByte); } |
2.WebBrowser与mshtml获取动态验证码
这个方法的大致思路:加载登录页面,获取动态验证码的HTML元素,再通过execCommand()实现浏览器的COPY功能将验证码保存到本地。实现该方法的简易的界面与代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
/* -------------------------------------------------------- * 作者:livezingy * * 博客:https://www.livezingy.com * * 开发环境: * Visual Studio V2012 * .NET Framework 4.5 * * 版本历史: * V1.0 2015年08月22日 通过webBrowser与mshtml获取动态验证码 --------------------------------------------------------- */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using mshtml;//需要提前添加引用:添加引用-->COM-->Microsoft HTML Object Library namespace LOGIN { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.txtUrl.Text = "http://www.nydus2015.info/login?callback=/loginbbs"; this.webBrowser1.Navigate(this.txtUrl.Text); } private void btnGetImage_Click(object sender, EventArgs e) { //取得验证码 HtmlElement ImgeTag = webBrowser1.Document.GetElementById("codeimg");//webBrowser1.Document.All["img"]; Image numPic = GetWebImage(webBrowser1, ImgeTag); // 得到验证码图片 pictureBox1.Image = numPic; } /// <summary> /// 返回指定WebBrowser中图片<IMG></IMG>中的图内容 /// </summary> /// <param name="WebCtl">WebBrowser控件</param> /// <param name="ImgeTag">IMG元素</param> /// <returns>IMG对象</returns> private Image GetWebImage(WebBrowser WebCtl, HtmlElement ImgeTag) { HTMLDocument doc = (HTMLDocument)WebCtl.Document.DomDocument; HTMLBody body = (HTMLBody)doc.body; IHTMLControlRange rang = (IHTMLControlRange)body.createControlRange(); IHTMLControlElement Img = (IHTMLControlElement)ImgeTag.DomElement; //图片地址 Image oldImage = Clipboard.GetImage(); rang.add(Img); rang.execCommand("Copy", false, null); //拷贝到内存 Image numImage = Clipboard.GetImage(); try { Clipboard.SetImage(oldImage); } catch { } return numImage; } } } |
3.调整WebBrowser的尺寸
我在使用WebBrowser产生过调整其尺寸的疑问,其实WebBrowser放置在我们窗体上的时候,它默认父容器中停靠,此时它会占据我们窗体的全部,而且没有办法调整它在父容器中的大小和位置。不过只要我们通过该控件右上角的小三角“取消在父容器中停靠”,我们就可以随意安排它的位置与大小了。
No Responses