• C# 利用 HttpWebRequest 和 HttpWebResponse 模拟登录有验证码的网站


    我们经常会碰到需要程序模拟登录一个网站,那如果网站需要填写验证码的要怎样模拟登录呢?
    这篇文章利用了 HttpWebRequest 和 HttpWebResponse 模拟登录了有验证码的网站。

    程序设计的界面很简单,三个TextBox分别输入用户名、密码和验证码,一个Image控件显示从网站请求到的验证码图片,还有两个按钮,一个换验证码,一个登录。

    写程序前,先用浏览器的开发者工具观察下登录页面有什么请求,我这里用的是 FireBug,下面两个图是在 FireBug 的网络面板中截的。

    可以看到打开登录页面时有个 GET 请求验证码的,在 FireBug 中可以看到:

    上面的图上可以看到这一句: Set-Cookie GUID=c89eabb62d9d4f35b491a8afd371b4ad; path=/

    这里请求的验证码页面保存了一个Cookie。

    然后我们输入验证码,点击“登录”的时候有个 POST 请求,在 FireBug 可以看到:

    这里的重点是这句:CodeStatus=&bkurl=&companyid=&username=test&password=test&Validate=yyxe

    从这里我们可以看到用户名、密码还有验证码提交的方式。

    下面大概说下程序的步骤:

    1. 请求验证码,显示在程序界面上,并且保存Cookie。

    2. 提交姓名、密码和验证码数据,获得响应。

    我这里是WPF程序,如果是Winform也类似。

    完整代码如下:

            CookieContainer cookies = null;
            string strCookies = string.Empty;
    
            private void btnChangeValidate_Click(object sender, RoutedEventArgs e)
            {
                GetValidateImage();
            }
    
            /// <summary>
            /// 获取验证码和Cookie
            /// </summary>
            private void GetValidateImage()
            {
                cookies = new CookieContainer();
                string url = "http://******/picturetimestamp.asp";  //验证码页面
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Accept = "*/*";
                request.Method = "GET";
                request.UserAgent = "Mozilla/5.0";
                request.CookieContainer = new CookieContainer(); //暂存到新实例
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    
                MemoryStream ms = null;
                using (var stream = response.GetResponseStream())
                {
                    Byte[] buffer = new Byte[response.ContentLength];
                    int offset = 0, actuallyRead = 0;
                    do
                    {
                        actuallyRead = stream.Read(buffer, offset, buffer.Length - offset);
                        offset += actuallyRead;
                    }
                    while (actuallyRead > 0);
                    ms = new MemoryStream(buffer);
                }
                response.Close();
    
                cookies = request.CookieContainer; //保存cookies
                strCookies = request.CookieContainer.GetCookieHeader(request.RequestUri); //把cookies转换成字符串
    
                BitmapImage bi = new BitmapImage();
                bi.BeginInit();
                bi.StreamSource = (Stream)ms;
                bi.EndInit();
                imgValidate.Source = bi;
            }
    
            private void btnLogin_Click(object sender, RoutedEventArgs e)
            {
                Login();
            }
    
            /// <summary>
            /// 登录
            /// </summary>
            /// <returns></returns>
            private string Login()
            {
                HttpWebRequest request = null;
                string url = "http://******/loginproc.asp";   //登录页面
                request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
    
                request.Accept = "*/*;";
                request.UserAgent = "Mozilla/5.0";
                request.ContentType = "application/x-www-form-urlencoded";
                request.AllowAutoRedirect = true;
                request.CookieContainer = cookies;
                request.KeepAlive = true;
    
                string postData = string.Format("username={0}&password={1}&Validate={2}&isautologin=1&Submit=", txtUserName.Text, txtPassword.Text, txtValidate.Text);  //这里按照前面FireBug中查到的POST字符串做相应修改。
                byte[] postdatabyte = Encoding.UTF8.GetBytes(postData);
                request.ContentLength = postdatabyte.Length;
    
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(postdatabyte, 0, postdatabyte.Length);
                }
    
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    
                string strWebData = string.Empty;
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    strWebData = reader.ReadToEnd();
                }
                return strWebData;
            }

    希望可以帮到有需要的人。

    原文地址:http://www.cnblogs.com/mib23/p/3913016.html

  • 相关阅读:
    Webservice接口和Http接口
    java多线程
    时间显示成一串阿拉伯数字
    jsp静态与动态包含的区别和联系
    解决Win10默认占用80端口
    JAVA中文乱码之解决方案
    相对路径与绝对路径的差异
    JSP静态包含和动态包含的区别和联系
    数据库Oracle
    智能指针shared_ptr的用法
  • 原文地址:https://www.cnblogs.com/mib23/p/3913016.html
Copyright © 2020-2023  润新知