这几天想学着做一个自动投票的工具;
代码如下:void vote(string key,int userid,string pass)
        {
            string url = WebSite + voteSite;
            string  param = "key="+key+"&id="+userid.ToString()+"&pass="+pass;
            //byte[] postdata = Encoding.ASCII.GetBytes(param);            //Encoding myEncoding = Encoding.GetEncoding("gb2312");
            string address = url + param;
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(address);
            req.ContentType = "application/x-www-form-urlencoded";
            req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GoogleT5; .NET CLR 2.0.50727)";
            req.Referer = site;
            //req.ContentLength = postdata.Length;
            req.Method = "POST";
            try
            {
                using (Stream reqStream = req.GetRequestStream())
                {
                    //reqStream.Write(postdata, 0, postdata.Length);
                    reqStream.Close();
                }
            }
            catch (WebException e)
            {
                MessageBox.Show(e.Message);
            }
        }--------------------------------------------------------------------------
死也提交不进去;测试页面为:http://bb.beingmate.com/photo/detail-14910.html
上面的测试规则为一个面页一个小时只能投一次票;通过页面正常的提交所产生的Header信息为(用Fiddler):如下:
POST /vote_.asp?key=b594&id=14910&pass=2723 HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Referer: http://bb.beingmate.com/photo/detail-14910.html
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GoogleT5; .NET CLR 2.0.50727)
Host: bb.beingmate.com
Content-Length: 0
Proxy-Connection: Keep-Alive
Pragma: no-cache
Cookie: cnzz_a887707=28; rtime=0; ltime=1218008354359; cnzz_eid=60832741-; 14929=1; ASPSESSIONIDSARSCBTQ=EALHPNAAEKOFHMKDMFGFHIDH
-------------------------------------
POST /vote_.asp?key=b594&id=14910&pass=2723 HTTP/1.1,其中key,id和pass值在模仿的时候没有错;
key:表示自身一个随机值;id:表示投票对象的id;pass表示验证码;我上面所使用的代码有什么问题吗?
我将
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(address);
改为:HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
然后在流里写入表单的值(postdata)?
但通过正常方式在Fiddler里面看,key=b594&id=14910&pass=2723 的值不是以表单的形式提交上去的,而是出现在QueryString里面。在Body里面根本就没有数据。
我做成了将需要提交的数据放在reqStream.Write(postdata, 0, postdata.Length)里加入,但提交不上去;但是提交评论是可以通过的(将提交内容话reqStream中提交可以成功);唯独提交投票不能通过;我的问题出在哪里呢?
真是好恼人。三天了,一直找不到问题所在;望高手帮忙!

解决方案 »

  1.   

    en!是的。如果机器重新启一次,或者IP地址发生变化的情况下:key的值才会发生变化;一般情况下不会改变的;
    可以将这个页面[http://bb.beingmate.com/photo/detail-14910.html]用webclient.downloaddata下载来来,在数据中可以找到key的值;一般情况下不会发生改变;
      

  2.   

    你没有带SESSION POST,当然有问题了,他的验证码要通过Cookie: cnzz_a887707=28; rtime=0; ltime=1218008354359; cnzz_eid=60832741-; 14929=1; ASPSESSIONIDSARSCBTQ=EALHPNAAEKOFHMKDMFGFHIDH 
    去和POST /vote_.asp?key=b594&id=14910&pass=2723 HTTP/1.1 中的2723去验证的.
      

  3.   

    这样吗?
    ----
    void vote(string key,int userid,string pass)
            {
                string url = WebSite + voteSite;
                string  param = "key="+key+"&id="+userid.ToString()+"&pass="+pass;
                //byte[] postdata = Encoding.ASCII.GetBytes(param);            //Encoding myEncoding = Encoding.GetEncoding("gb2312");
                string address = url + param;
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(address);
                wr.CookieContainer = myCookieContainer;
                req.ContentType = "application/x-www-form-urlencoded";
                req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GoogleT5; .NET CLR 2.0.50727)";
                req.Referer = site;
                //req.ContentLength = postdata.Length;
                req.Method = "POST";
                try
                {                using (Stream reqStream = req.GetRequestStream())
                    {
                        //reqStream.Write(postdata, 0, postdata.Length);
                        reqStream.Close();
                    }
                }
                catch (WebException e)
                {
                    MessageBox.Show(e.Message);
                }
                using (HttpWebResponse wr = req.GetResponse())
                {
                    wr.Cookies = myCookieContainer.GetCookies(wr.RequestUri);
                } 
    }-------------------------------------------------------------
    但这里的Cookie在提交的时候只是 ASPSESSIONIDSARSCBTQ=EALHPNAAEKOFHMKDMFGFHIDH 
    而没有cnzz_a887707=28; rtime=0; ltime=1218008354359; cnzz_eid=60832741-; 14929=1; 
    这是为什么?
      

  4.   

    HttpWebRequest有个类似cookie的属性
      

  5.   

    查查里面的属性cookiecontainer
    http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest_properties.aspx
      

  6.   

    lz为什么将编码注释掉?
     //byte[] postdata = Encoding.ASCII.GetBytes(param);
    //Encoding myEncoding = Encoding.GetEncoding("gb2312");
    你是不是从网上看的这段代码然后copy下来一运行
    //req.ContentLength = postdata.Length;
    这句话就报错?所以你就注释掉。
    记住C#的默认编码是UTF-8,你不进行编码是会出错的。
    前段时间搞过httpwebrequest,
    给你看看我测试通过的例子:
      HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);   //根据登录页面创建请求 
                    req.Method = "POST";   //一定要是大写
                    req.ContentType = "application/x-www-form-urlencoded";
                    req.AllowAutoRedirect = false;
                    cookieCon = new CookieContainer();
                    req.CookieContainer = cookieCon;   //创建存储登录后的对象的CookieContainer  ,内容主要包括sessionID 和 form验证的cookie                 StringBuilder UrlEncoded = new StringBuilder();
                    Char[] reserved =   { '?', '=', '&' };
                    byte[] SomeBytes = null;                if (paramList != null)     //根据传入的数据进行Post
                    {
                        int i = 0, j;
                        while (i < paramList.Length)
                        {
                            j = paramList.IndexOfAny(reserved, i);
                            if (j == -1)
                            {
                                UrlEncoded.Append(HttpUtility.UrlEncode(paramList.Substring(i, paramList.Length - i)));
                                break;
                            }
                            UrlEncoded.Append(HttpUtility.UrlEncode(paramList.Substring(i, j - i)));
                            UrlEncoded.Append(paramList.Substring(j, 1));
                            i = j + 1;
                        }
                        SomeBytes = Encoding.UTF8.GetBytes(UrlEncoded.ToString());
                        req.ContentLength = SomeBytes.Length;
                        Stream newStream = req.GetRequestStream();
                        newStream.Write(SomeBytes, 0, SomeBytes.Length);
                        newStream.Close();
      

  7.   

    Stream newStream=myRequest.GetRequestStream();
                // Send the data.
                newStream.Write(data,0,data.Length);
      

  8.   

    首先,打开页面http://bb.beingmate.com/photo/detail-14910.html 
    得到cookie和 页面的html ,然后立刻通过cookie到http://bb.beingmate.com/getcode.asp中读取验证码
    通过html中有一个onclick=\"vote('14910','xxxx')之类的字样,得到投票的key
    代码如下:
     private string GetHTMLstring(string url)
            {
                HttpWebRequest httpWebRequest;
                HttpWebResponse webResponse;
                Stream stream;
                byte[] byteRequest ={ };            httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);  //加载URL
                httpWebRequest.ContentType = "application/x-www-form-urlencoded";
                httpWebRequest.Method = "Post";
                httpWebRequest.ContentLength = byteRequest.Length;  //设置Header            stream = httpWebRequest.GetRequestStream();
                stream.Write(byteRequest, 0, byteRequest.Length); //POST信息
                stream.Close();            webResponse = (HttpWebResponse)httpWebRequest.GetResponse(); //收到应答
                StreamReader sr = new StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.Default);            string c = webResponse.Headers.Get("Set-Cookie");
                cookie = c.Substring(0, c.IndexOf(";"));
                textBox1.Text = cookie;
                Image img = new Bitmap(GetYZMpicture("http://bb.beingmate.com/getcode.asp"));//获得验证码图片
                pictureBox1.Image = img;            return (sr.ReadToEnd());
            }        private Stream GetYZMpicture(string url)  //发送Cookie取得验证码
            {
                long contentLength;
                HttpWebRequest httpWebRequest;
                HttpWebResponse webResponse;
                Stream stream;
                byte[] byteRequest ={ };            httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);  //加载URL
                CookieContainer cookie_container = new CookieContainer();     //加载Cookie
                cookie_container.SetCookies(new Uri(url), cookie);
                httpWebRequest.CookieContainer = cookie_container;            httpWebRequest.ContentType = "application/x-www-form-urlencoded";
                httpWebRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
                httpWebRequest.Method = "Post";
                httpWebRequest.ContentLength = byteRequest.Length;  //设置Header            stream = httpWebRequest.GetRequestStream();
                stream.Write(byteRequest, 0, byteRequest.Length); //POST信息
                stream.Close();            webResponse = (HttpWebResponse)httpWebRequest.GetResponse(); //收到应答
                stream = webResponse.GetResponseStream();
                contentLength = webResponse.ContentLength;            byte[] outBytes = new byte[contentLength]; //转换为Byte
                outBytes = ReadFully(stream);
                stream.Close();            return (new MemoryStream(outBytes));        }        public static byte[] ReadFully(Stream stream)
            {
                byte[] buffer = new byte[128];
                using (MemoryStream ms = new MemoryStream())
                {
                    while (true)
                    {
                        int read = stream.Read(buffer, 0, buffer.Length);
                        if (read <= 0)
                            return ms.ToArray();
                        ms.Write(buffer, 0, read);
                    }
                }
            }        private void button4_Click(object sender, EventArgs e)
            {
                backstr=GetHTMLstring("http://bb.beingmate.com/photo/detail-14910.html");
                votestr = "http://bb.beingmate.com/vote_.asp?key=" + backstr.Substring(backstr.IndexOf("onclick=\"vote('14910'") + 23, 4) + "&id=14910&pass=";
            }其中textBox1为显示cookie的,pictureBox1.Image 为显示当前cookie所对应的验证码.
    第二步,手工输入验证码,(自动的高手自己去做吧)到textBox6 (变量有些乱,上面的button4也是)点击一个按钮,模拟投票.
            private void button1_Click(object sender, EventArgs e)
            {
                votestr += textBox6.Text;
                GetVoteResult(votestr);
            }这时votestr为 /vote_.asp?key=b594&id=14910&pass=2723 的串public void GetVoteResult(string url)  //发送投票
            {
                HttpWebRequest httpWebRequest;
                HttpWebResponse webResponse;
                Stream stream;
                byte[] byteRequest = System.Text.Encoding.Default.GetBytes("");            httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);  //加载URL
                CookieContainer cookie_container = new CookieContainer();     //加载Cookie
                cookie_container.SetCookies(new Uri(url), cookie);
                httpWebRequest.CookieContainer = cookie_container;            httpWebRequest.Method = "POST";
                httpWebRequest.ContentType = "application/x-www-form-urlencoded";
                httpWebRequest.ContentLength = byteRequest.Length;
                httpWebRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, application/x-shockwave-flash, */*";
                httpWebRequest.Referer = "http://bb.beingmate.com/photo/detail-14910.html";
                httpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)";            stream = httpWebRequest.GetRequestStream();
                stream.Write(byteRequest, 0, byteRequest.Length); //POST信息
                stream.Close();            webResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                StreamReader sr = new StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.Default);
                sr.Close();
                webResponse.Close();        }
    通过代码将session和验证码等post出去.
    这样,投票就成功了.
    但是成功后没有返回的信息,只能通过打开IE查看投票数+1了,并且立刻投票说需要间隔1小时.所以应该是成功了.
      

  9.   

    那就用get
    看那个网站是用什么方式网页处理的喽~自动投票页是在登录页???
    要获取COOKIES在提交后就可以从RESPONSE流读取,保存在SESSION里也可,下回,就用HTTPWEBREQUEST的COOKIECONTAINER赋值为保存的SESSION,具体不知道那个网站的处理用户交互得到数据的机制.