最近弄了个论坛,用的是discuz 2.5,小弟想弄个C#程序批量实现注册。
根据抓包发现disucz的post方式有点变态,使用的是multipart/form-data;方式注册。这玩意一般都是用于文件上传,于是根据文件上传的方式模拟post。但是发现还是不能注册,不知道为什么。请问哪位大神做过discuz 2.5版本的注册功能?
抓包得到的数据如下
------WebKitFormBoundary6hxIK7LrJDWuJFDk
Content-Disposition: form-data; name="regsubmit"yes
------WebKitFormBoundary6hxIK7LrJDWuJFDk
Content-Disposition: form-data; name="formhash"fe966612
------WebKitFormBoundary6hxIK7LrJDWuJFDk
Content-Disposition: form-data; name="referer"http://domainname.com/bbs/./
------WebKitFormBoundary6hxIK7LrJDWuJFDk
Content-Disposition: form-data; name="activationauth"
------WebKitFormBoundary6hxIK7LrJDWuJFDk
Content-Disposition: form-data; name="AuuE85"asfsadfasdf【这里是账号】
------WebKitFormBoundary6hxIK7LrJDWuJFDk
Content-Disposition: form-data; name="JW0BP3"123456【这里是密码】
------WebKitFormBoundary6hxIK7LrJDWuJFDk
Content-Disposition: form-data; name="GsAJ28"123456【这里是确认密码】
------WebKitFormBoundary6hxIK7LrJDWuJFDk
Content-Disposition: form-data; name="HeuwYy"[email protected]【这里是邮箱】
------WebKitFormBoundary6hxIK7LrJDWuJFDk
Content-Disposition: form-data; name="regsubmit"true
------WebKitFormBoundary6hxIK7LrJDWuJFDk--
小弟写程序模拟出来的结果跟上面一模一样,但是就是无法注册成功。
核心代码如下:                string strPostHeader = ss.ToString();//这里的ss为上面的数据。
                byte[] postHeaderBytes = Encoding.UTF8.GetBytes(strPostHeader);
                // 根据uri创建HttpWebRequest对象 
                HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(new Uri(url));
                httpReq.Method = "POST";
                //对发送的数据不使用缓存 
                httpReq.AllowWriteStreamBuffering = false;
                //设置获得响应的超时时间(300秒) 
                httpReq.Timeout = 300000;
                httpReq.Accept = "text/html, application/xhtml+xml, */*";
                httpReq.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
                httpReq.ContentType = "multipart/form-data; boundary=" + strBoundary.Substring(0);
                httpReq.Headers.Add("Pragma", "no-cache");
                httpReq.Headers.Add("Accept-Language", "zh-CN");
                long length = postHeaderBytes.Length;
                httpReq.ContentLength = length;
                httpReq.Referer = "http://domainname.com/bbs/member.php?mod=register";
                httpReq.KeepAlive = true;
                httpReq.ServicePoint.Expect100Continue = false;
                httpReq.CookieContainer = cookies;
                try
                {
                    Stream postStream = httpReq.GetRequestStream();
                    postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
                    postStream.Close();
                    //获取服务器端的响应 
                    WebResponse webRespon = httpReq.GetResponse();
                    Stream s = webRespon.GetResponseStream();
                    StreamReader sr = new StreamReader(s);
                    //读取服务器端返回的消息 
                    String sReturnString = sr.ReadToEnd();
                    s.Close();
                    sr.Close();
                }
                catch (Exception)
                {                }

解决方案 »

  1.   

    不清楚disucz
    你在注册页面是否能抓到post过来的数据?
      

  2.   

    可以的,但是那鸟东西老变态了。不是用的普通方式提交数据到后台,而是使用文件上传用的multipart/form-data;方式post数据到后台。
      

  3.   

    你要注意 formhash,先用程序访问页面,获取html及CookieContener(不会拼了),再从html中获取formhash,拼取上传数据,进行上传才行!!!
      

  4.   

    额 这个倒没见过。不过那就要麻烦多了 你得分析流数据 然后取得表单的值
    http://topic.csdn.net/t/20051208/13/4446033.html
    参考下。而你的post过去的数据 虽然你可能表面看起来确实符合discuz那边的注册数据
    但是可能是有点不同的 肯定是有一些规则导致你的数据不是很符合那边接受的格式。
      

  5.   


                    string strBoundary = "";
                    strBoundary = "-----------------------------" + DateTime.Now.Ticks.ToString("x");
                    //请求头部信息 
                    StringBuilder ss = new StringBuilder();
                    ss.Append(strBoundary + "\r\n");
                    ss.Append("Content-Disposition: form-data; name=\"regsubmit\"\r\n\r\n");
                    ss.Append("yes\r\n");
                    ss.Append(strBoundary + "\r\n");
                    ss.Append("Content-Disposition: form-data; name=\"formhash\"\r\n\r\n");
                    ss.Append(formhash + "\r\n");//这里的formhash是我访问页面后得到的,cookies也传过来了
                    ss.Append(strBoundary + "\r\n");
                    ss.Append("Content-Disposition: form-data; name=\"referer\"\r\n\r\n");
                    ss.Append("http://domainname.com/bbs/./\r\n");
                    ss.Append(strBoundary + "\r\n");
                    ss.Append("Content-Disposition: form-data; name=\"activationauth\"\r\n\r\n");
                    ss.Append("\r\n");
                    ss.Append(strBoundary + "\r\n");
                    ss.Append("Content-Disposition: form-data; name=\"AuuE85\"\r\n\r\n");
                    ss.Append(string.Format("{0}\r\n", username));
                    ss.Append(strBoundary + "\r\n");
                    ss.Append("Content-Disposition: form-data; name=\"JW0BP3\"\r\n\r\n");
                    ss.Append(string.Format("{0}\r\n", password));
                    ss.Append(strBoundary + "\r\n");
                    ss.Append("Content-Disposition: form-data; name=\"GsAJ28\"\r\n\r\n");
                    ss.Append(string.Format("{0}\r\n", okpass));
                    ss.Append(strBoundary + "\r\n");
                    ss.Append("Content-Disposition: form-data; name=\"HeuwYy\"\r\n\r\n");
                    ss.Append(string.Format("{0}\r\n", email));
                    ss.Append(strBoundary + "\r\n");
                    ss.Append("Content-Disposition: form-data; name=\"regsubmit\"\r\n\r\n");
                    ss.Append("true\r\n");
                    ss.Append(strBoundary + "--\r\n");
      

  6.   

    麻烦你帮我看下核心的代码是否有误。我用Fiddler截获的封包发现WebForms这个选项卡下的Content-Type部分的内容无法正常解析成类似QueryString一样,一行一行的。我上传个图片给你看看。
    正常情况应该是这样的
      

  7.   

    解决问题,谢谢各位同学帮忙。
    实际上是这句话出了问题//这里出了问题
    httpReq.ContentType = "multipart/form-data; boundary=" + strBoundary.Substring(0);
    //实际上应该是
    httpReq.ContentType = "multipart/form-data; boundary=" + strBoundary.Substring(0);
    //把2打成0了,这样的问题还真难发现。看来做事还真的要注意细节啊。o(︶︿︶)o 唉,其实我感觉我每次搞模拟都非常细心,没想到还是出这样的问题。悲剧
      

  8.   

    暴汗,搞飞机。应该是这样://实际上应该是
    httpReq.ContentType = "multipart/form-data; boundary=" + strBoundary.Substring(2);搞了晚上,确实头晕了。
      

  9.   

    其实3楼的哥们说的是一点都没错,之前我也以为是这里错了,而且我还加上了用户名和邮箱是否重复的验证。但是加上了formhash还是不行,结果是我把2打成0搞错了。真郁闷,真悲剧啊。