设置HttponlyCookie解决mshtml编程无法获取验证码图片流

最近给客户做的项目有一个新需求,客户需要在打开的IE浏览器中做自动登录,登录的页面上有神兽验证码.解决验证码的方案是找第三方平台打码.这样就有一个问题,如何把正确的验证码传给第三方打码平台.

大家都知道,验证码是随机生成的,每次图片的URL访问都会变化,这样传路径给第三方,图片已经不是页面上的那张图了.于是想到了两种思路去解决这个问题:

1.通过截屏的方式把验证码截取出来再传给第三方打码.

2.抓到IE的Cookie与所有特征参数,利用这些参数发起Request模拟刷新验证码.

由于方式1本人才疏学浅,之前没有研究过这方面相关的知识,于是果断放弃,决定采取plan B.

使用方式2时发现一个问题,SessionID设置了httponly,而这个设置让我们无法直接通过接口读取到httponly的Cookie.这就无法伪装成IE浏览器去刷新验证码了.因为没有SessionID呀,服务器不认识我呀.于是再转换思路,决定先设置好IE的Cookie后再打开网站,这样服务器就能认识我了.能认识我就好办了,再去完成模拟刷新验证码的问题.换个思路后开始重新进行:

1.首先通过HttpRequest请求得到网站的所有Cookie,包括Httponly的.

2.调用wininet.dll给IE浏览器设置我们得到的Cookie.附上设置Cookie的核心代码(网上找的,如有侵权请见谅)

private const int INTERNET_COOKIE_HTTPONLY = 0x00002000;
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool InternetGetCookieEx(string pchURL, string pchCookieName, StringBuilder pchCookieData, ref
System.UInt32 pcchCookieData, int dwFlags, IntPtr lpReserved); [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int InternetSetCookieEx(string lpszURL, string lpszCookieName, string lpszCookieData, int dwFlags,
IntPtr dwReserved);
private static string GetCookies(string url)
{
uint datasize = 256;
StringBuilder cookieData = new StringBuilder((int)datasize);
if (!InternetGetCookieEx(url, null, cookieData, ref datasize, 0x2000, IntPtr.Zero))
{
if (datasize < 0)
return null;
cookieData = new StringBuilder((int)datasize);
if (!InternetGetCookieEx(url, null, cookieData, ref datasize, 0x00002000, IntPtr.Zero))
return null;
}
return cookieData.ToString();
}
public static string SetCookieForIE(string url, CookieCollection cookiestring, string path = "/")
{
try
{
foreach (Cookie c in cookiestring)
{
string name = c.Name;
string value = c.Value + ";expires=" + DateTime.Now.AddDays(1).ToString("r");
InternetSetCookieEx(url, name, value, INTERNET_COOKIE_HTTPONLY, IntPtr.Zero);
}
return GetCookies(url);
}
catch (Exception)
{
return "false";
throw;
}
}

3.设置好Cookie后启动IE打开网站,这时使用的SessionID就是我们设置的了,然后用HttpRequst请求刷新验证码得到图片流,传给第三方平台打码得到结果,执行登录,问题解决.

我采用的解决思路就是模拟刷新验证码,如果有其他小伙伴看了此文章有不明白之处,欢迎留言,请轻喷.

上一篇:Selenium2学习-039-WebUI自动化实战实例-文件上传下载


下一篇:Java与Python比较心得01