以前发了一个,没有解决,再发一次,看看有没有牛人
问题:
我在使用winform模拟登录时,现在的网页要输入验证码,当然我是手工输入数字部分了,但是总提示验证码不对。我看了不少的资料。后来看到有人提示,先request,得到验证图片,把cookie保留住,然后用cookie登录login网页,发送用户名和密码。我试了一下,这方法在IE中可以用。而且必须在同一个IE窗口中,可以显示成功,
如果在一个IE窗口中输入:
http://verify.bbs.sina.com.cn/imgSerial.php?id=331&s=0.966563739231137
当然后面的参数是随便输入的.
在IE窗口中出现一个图型的数字.
然后再在同一个IE窗口中输入
http://forum.auto.sina.com.cn/cgi-bin/login.cgi?author=mp3diyhuang&passwd=123456&gid=25&fid=331&pin=图片中的数字
就可以登录上了.
如果在别一个IE窗口中输入则不行.用Winform 如何模拟?
上面我将主要的代码贴了出来. 先显示图片, 然后将再次提交,Cookie都设置好了,但总也不行.有谁能看看有什么问题.
上面的sina的用户名都是没有问题的.是可以登录的.请教一下.

给100分。
如果在一个IE窗口中输入:
http://verify.bbs.sina.com.cn/imgSerial.php?id=331&s=0.966563739231137
当然后面的参数是随便输入的.
在IE窗口中出现一个图型的数字.
然后再在同一个IE窗口中输入
http://forum.auto.sina.com.cn/cgi-bin/login.cgi?author=mp3diyhuang&passwd=123456&gid=25&fid=331&pin=图片中的数字
就可以登录上了.
如果在别一个IE窗口中输入则不行.
用Winform 如何模拟?
上面我将主要的代码贴了出来. 先显示图片, 然后将再次提交,Cookie都设置好了,但总也不行.有谁能看看有什么问题.
上面的sina的用户名都是没有问题的.是可以登录的.请教各位大侠。
代码:当然有的控件是没有的。
CookieCollection cookieGet = new CookieCollection();
        CookieCollection cookieGetlogin = new CookieCollection();
        CookieContainer onecontain= new CookieContainer();
        HttpWebRequest myRequest ;private void buttonlogin_Click(object sender, EventArgs e)
        {
            string address = @"http://forum.auto.sina.com.cn/cgi-bin/login.cgi" ;
            HttpWebResponse myresponse = null;
            //HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(address);
            myRequest = (HttpWebRequest)WebRequest.Create(address);            //myRequest.UserAgent = @" Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; (R1 1.5); .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
            //myRequest1.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.1.4322)"; // 模拟使用IE在浏览
            myRequest.ContentType = "text/html";
            myRequest.KeepAlive = true;
            //myRequest.ProtocolVersion = HttpVersion.Version10;
            myRequest.AllowAutoRedirect = false;
          
            myRequest.Accept = "*/*"; //接受任意文件
                      //        
            string postdata = @"author=mp3diyhuang&passwd=123456&gid=25&fid=331&pin="+textBoxdigital .Text.Trim () ;
           // string postdata = "";            byte[] byte1 = Encoding.Default.GetBytes(postdata);
            myRequest.ContentType = "application/x-www-form-urlencoded";
            myRequest.CookieContainer = onecontain;//设置成了一样的cookiecontainer
            myRequest.Method = "post";//post上传方式
            myRequest.ContentLength = byte1.Length;
//将原来的显示图片中的cookieloing给myrequest.
            if (cookieGetlogin != null)
            {
                System.Uri u = new Uri(address);
                                foreach (System.Net.Cookie c in cookieGetlogin)
                {
                    c.Domain = u.Host;
                }                myRequest.CookieContainer.Add(cookieGetlogin);
            }            Stream newStream = myRequest.GetRequestStream();            try
            {
                newStream.Write(byte1, 0, byte1.Length);
            }
            catch (Exception er)
            {
                MessageBox.Show(er.Message);
            }
            try
            {
                myresponse = (HttpWebResponse)myRequest.GetResponse();                //CookieCollection cookieGet, cookieGet1;
               
            }
            catch (Exception errmsg)
            {
                MessageBox.Show(errmsg.Message);
            }
            HttpWebResponse response = (HttpWebResponse)myRequest.GetResponse();
            cookieGet = response.Cookies;
            string tempstr = "blank";
            for (int i = 0; i < cookieGet.Count; i++)
            {
                tempstr += "\r\n" + cookieGet[i].Name;
                tempstr += "\r\n" + cookieGet[i].Value;
            }            textBoxcontent.Text = tempstr;
            
            Stream responseStream = response.GetResponseStream();
            StreamReader readStream = new StreamReader(responseStream, System.Text.Encoding.Default);
            //readStream.Read(charbf, 1, 35211); string page=null;
            string pagecheckstring = readStream.ReadToEnd();
            //textBoxcontent.Text = pagecheckstring;            // webBrowserweb .Navigate ("about:blank");
            webBrowserweb.DocumentText = pagecheckstring;public void showpicturedigital()
        {
            string forumstring, forumtype;
            string address;
            string htmlCode = "";
            //forumstring = "109";
               forumstring = "";            address = @"http://verify.bbs.sina.com.cn/imgSerial.php?id=331&s=0.966563739231137";
           
             myRequest = (HttpWebRequest)WebRequest.Create(address);
            
            myRequest.UserAgent = @" Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; (R1 1.5); .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
           
            myRequest.KeepAlive = true;
            
            myRequest.Accept = " */*";
            
            myRequest.Method = "get";
            
             myRequest.CookieContainer = onecontain;//cookie容器,
           
            Image img = null;
            HttpWebResponse response = (HttpWebResponse)myRequest.GetResponse();
            
            Stream responseStream = response.GetResponseStream();
            img = Image.FromStream(responseStream);
            StreamReader readStream = new StreamReader(responseStream, System.Text.Encoding.Default);
            //readStream.Read(charbf, 1, 35211); string page=null;
            string pagecheckstring = readStream.ReadToEnd();
            cookieGetlogin = response.Cookies;
            string tempstr = "blank";
            for (int i = 0; i < cookieGetlogin.Count; i++)
            {
                tempstr += "\r\n" + cookieGetlogin[i].Name;
                tempstr += "\r\n" + cookieGetlogin[i].Value;
            }
            textBoxcontent.Text = tempstr;
            pictureBoxcheckcode.Image = img;
           
        }

解决方案 »

  1.   

    模拟登陆是一、首次登陆
    1、取验证码图片
    2、用GDI+对图片进行识别(很麻烦,很难搞出通用的,基本上是一个网站一个特征库)
    3、以POST方法传输  用户名,密码,验证码(比如表单用户名是UserName,那么用户就是"UserName=用户名")
    4、保留登陆后的Cookice,留代以后使用二、开始发帖
    1、假如有验证码同上
    2、以POST方法传输表单部分(同上),如果有Get部分,比如Post.asp?id=134,那么构造URI的时候直接把Post.asp?id=134作为URI
    3、传输之前设置本次传输的Cookice是登陆时候保留的Cookice流程就是这样,编码是个很复杂的。虽然实现功能简单,但是要实现多线程,群发(制定群发列表),发新帖后自动定帖(正则表达式抓取新帖ID),切换用户(申请很多用户切换发帖子),每隔时间自动注册用户,根据设置好的回复(比如100)条,没次只取一条去回复
    ......逻辑才是值钱的东西。
      

  2.   

    谢谢,不过还有问题。
    1,取验证码图片
        在这个当中息么保证取到的值是可用于下次pos时的验证码。在我的程序中就总说验证码不对。2、用GDI+对图片进行识别(很麻烦,很难搞出通用的,基本上是一个网站一个特征库)
    3、以POST方法传输  用户名,密码,验证码(比如表单用户名是UserName,那么用户就是"UserName=用户名")
    4、保留登陆后的Cookice,留代以后使用
      

  3.   

    @shenghuang(huangsheng) 在同一次取得和发送之间取的验证码图片可以通过识别验证码是图形识别技术的一个小应用,比如图片上有数字1234,程序怎么就知道那是1234呢?只能根据这个网站验证码的特征(基本上每个网站的验证码样子都不一样,象腾讯是中文的...)判别出来。using System.Netprivate CookieContainer Cookies = null...........
    //http://www.163.com/index.asp?id=114只是打个比方
    HttpWebRequest myHttpWebRequest1 = CType(WebRequest.Create("http://www.163.com/index.asp?id=114"), HttpWebRequest)if(this.Cookies!=null)
    {
          //假如定义的Cookies不为空
          //把本次发送对象myHttpWebRequest1的Cookies定为定义的Cookies
          myHttpWebRequest1.CookieContainer = this.Cookies;
    }
    else
    {
          //假如定义的Cookies为空
          //把本次发送对象myHttpWebRequest1的Cookies定为 新的
          //把取得的新Cookies给全局变量this.Cookies 
          myHttpWebRequest1.CookieContainer = New CookieContainer();
          this.Cookies = myHttpWebRequest1.CookieContainer;
    }
      

  4.   

    假如登陆窗口HTML代码如下
    .....
    <form action="UserLogin.aspx?action=yes" method="post" name="Login">
    .......
    <input name="username" type="text" class="Logininput2" />  //用户名
    <input name="password" type="password" class="Logininput2" />  //密码
    <input name="CheckCode" type="text" class="CodeInput" id="CheckCode" size="6" maxlength="6" tabindex="3">   //验证码
    <img src="../Serverlet/CodeGif.aspx" />   //验证码图片
    .......
    ***********************************************************************************using System.Netprivate CookieContainer Cookies = null...........
    HttpWebRequest myHttpWebRequest1 = CType(WebRequest.Create("传输域名/UserLogin.aspx?action=yes"), HttpWebRequest)
    //假定登陆信息以Cookies储存
    if(this.Cookies!=null)
    {
          //假如定义的Cookies不为空
          //把本次发送对象myHttpWebRequest1的Cookies定为定义的Cookies
          myHttpWebRequest1.CookieContainer = this.Cookies;
    }
    else
    {
          //假如定义的Cookies为空
          //把本次发送对象myHttpWebRequest1的Cookies定为 新的
          //把取得的新Cookies给全局变量this.Cookies 
          myHttpWebRequest1.CookieContainer = New CookieContainer();
          this.Cookies = myHttpWebRequest1.CookieContainer;
    }//这里对验证码验证就可以了myHttpWebRequest1.AllowAutoRedirect = true;
    myHttpWebRequest1.ContentType = "application/x-www-form-urlencoded";
    myHttpWebRequest1.Method = "POST";
    myHttpWebRequest1.Timeout = 20 * 1000;Stream postStream = myHttpWebRequest1.GetRequestStream();
    //请注意postStr的值与上面html的对比,username为用户名表单的name ....
    string postStr = "username=admin&password=123456&CheckCode=" + "识别出的验证码"
    Byte[] ByteArray = System.Text.Encoding.GetEncoding("gb2312").GetBytes(postStr);
    postStream.Write(ByteArray, 0, postStr.Length);
    postStream.Close();.....................
      

  5.   

    我是这么想的,也是这么写的,可对于上面的sina的网页就是不行,不知道是不是新浪有什么特别的。还是我写的各序有问题。不带验证码的网页我没有问题,是可以登录的。
    代码已经贴在了上面,可不可以麻烦你在程序里试一下。可不可以运行过。我的结果就是验证码不对,已经搞了好长时间了,快死了。
    谢谢。
      

  6.   

    关键是,你在提交验证码的时候页面会进行一次刷新,这样,你的验证码其实已经不是你上次输入的那样了。所以总会提示错误。
    你可以把生成验证码的代码放到
    if(!IsPostBack)
    {}
    中试试~~~~~~~~~~~~~~~~~~~~~~~~
      

  7.   

    没有明白,
    我是运行了一次显示验证码的网页,
    http://verify.bbs.sina.com.cn/imgSerial.php?id=331&s=0.966563739231137,显示了图片,然后用的
    http://forum.auto.sina.com.cn/cgi-bin/login.cgi   发送数据下面的数据author=mp3diyhuang&passwd=123456&gid=25&fid=331&pin=图片中的数字if(!IsPostBack)
    {}
    没有明白。
    难道我显示一个图片会出现了两次。盼望能说详细些。  IsPostBAck是什么?