0

http://www.conquerclub.com/game.php?game=13025037

请问有谁知道我如何以编程方式登录到该地址,然后使用 HttpWebRequest/HttpWebResponse 之类的东西将页面的所有 html 作为字符串返回。

用户名 - “testuser1”

密码 - “测试”

(我已经使用这些凭据在网站上创建了一个帐户,因此它实际上会登录)

到目前为止,我有这个

private void toolStripButton1_Click(object sender, EventArgs e)
{
    var request = WebRequest.Create("http://www.conquerclub.com/game.php?game=13025037");
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    StreamReader reader = new StreamReader(response.GetResponseStream());
    richTextBox1.Text = reader.ReadToEnd();
}

这会自动重定向并返回登录页面的 html。如何通过用户名和密码自动登录,以便它检索游戏页面?

我知道在这方面有很多类似的问题,我花了几个小时尝试不同的事情,但什么都做不了。

编辑:-

对此进行了进一步调查,该站点使用 cookie 进行登录。

尝试了此代码,但仍然只是返回登录页面。

private void toolStripButton1_Click(object sender, EventArgs e)
{
    string loginUri = "http://www.conquerclub.com/login.php";
    string username = "testuser1";
    string password = "testing";
    string reqString = "username=" + username + "&password=" + password;
    byte[] requestData = Encoding.UTF8.GetBytes(reqString);

    CookieContainer cc = new CookieContainer();
    var request = (HttpWebRequest)WebRequest.Create(loginUri);
    request.Proxy = null;
    request.AllowAutoRedirect = false;
    request.CookieContainer = cc;
    request.Method = "post";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = requestData.Length;
    using (Stream s = request.GetRequestStream())
        s.Write(requestData, 0, requestData.Length);

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        if (response.Cookies != null)
        {
            foreach (Cookie c in response.Cookies)
                Console.WriteLine(c.Name + " = " + c.Value);
        }
    }

    string newloginUri = "http://www.conquerclub.com/game.php?game=13025037";
    HttpWebRequest newrequest = (HttpWebRequest)WebRequest.Create(newloginUri);
    newrequest.Proxy = null;
    newrequest.CookieContainer = cc;
    using (HttpWebResponse newresponse = (HttpWebResponse)newrequest.GetResponse())
    using (Stream resSteam = newresponse.GetResponseStream())
    using (StreamReader sr = new StreamReader(resSteam))
        richTextBox1.Text = sr.ReadToEnd();
}

发现底部登录游戏页面的代码可以通过首先手动登录同时在firefox上使用fiddler然后复制并粘贴cookie并将它们硬编码到newrequest中来工作。

string newloginUri = "http://www.conquerclub.com/game.php?game=13025037";
HttpWebRequest newrequest = (HttpWebRequest)WebRequest.Create(newloginUri);
newrequest.Proxy = null;
newrequest.CookieContainer = new CookieContainer();
newrequest.CookieContainer.Add(new Uri("http://www.conquerclub.com"), new Cookie("PHPSESSID","86bte1ipainiq760vm2flv4h13"));
newrequest.CookieContainer.Add(new Uri("http://www.conquerclub.com"), new Cookie("phpbb3_jer7c_u", "648113"));
newrequest.CookieContainer.Add(new Uri("http://www.conquerclub.com"), new Cookie("phpbb3_jer7c_k", ""));
newrequest.CookieContainer.Add(new Uri("http://www.conquerclub.com"), new Cookie("phpbb3_jer7c_sid", "3eebb0771a68c4a58581e495c34b2c93"));
using (HttpWebResponse newresponse = (HttpWebResponse)newrequest.GetResponse())
using (Stream resSteam = newresponse.GetResponseStream())
using (StreamReader sr = new StreamReader(resSteam))
    richTextBox1.Text = sr.ReadToEnd();

这将返回我想要的游戏页面,但无法弄清楚如何让登录正常工作,以便它返回正确的 cookie。在调试代码时,返回的 cookie 与我在提琴手中看到的完全不同,所以看起来它只是没有登录。

4

2 回答 2

2

您编写的代码对给定的 URL 进行了 GET;但是,要在登录时检索页面的内容,您需要通过传入所有表单变量并发出 POST 请求来假装您的 WebRequest 实际上正在填写表单。

http://msdn.microsoft.com/en-us/library/debx8sh9.aspx很好地介绍了您需要的步骤。以下内容并非 100% 完成,但应该让您朝着正确的方向迈出一步:

var request = WebRequest.Create("http://www.conquerclub.com/login.php");
request.Method = "POST";

var parameters = new Dictionary<string, string> { 
    { "username", "testuser1" }, 
    { "password", "testing" }, 
    { "redirect", "game.php?game=13025037" }, 
    { "direct", "63###www.conquerclub.com###" }, 
    { "protocol", "HTTP" }, 
    { "submit", "Login" } };

var content = string.Join( "&", ( from p in parameters select p.Key + "=" + HttpUtility.UrlEncode( p.Value) ).ToArray() ); ;

byte[] bytes = new byte[content.Length * sizeof(char)];
System.Buffer.BlockCopy(content.ToCharArray(), 0, bytes, 0, bytes.Length);

request.ContentLength = bytes.Length;
request.ContentType = "application/x-www-form-urlencoded";

Stream dataStream = request.GetRequestStream();
dataStream.Write( bytes, 0, bytes.Length );
dataStream.Close();

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string result = reader.ReadToEnd();

请注意,content包括在屏幕上不可见的各种值;这些可以通过查看表单的源代码来查看,或者(更容易)通过使用您选择的浏览器调试工具栏上的“网络”选项卡并监控提交表单时发送的数据。

于 2013-07-25T23:03:29.307 回答
0

您需要模拟登录过程。查看登录页面的 HTML 代码,找出三件事:

  1. 发送请求的<form>,特别是表单的目标(在属性中找到action)。
  2. 找出发送数据的方法(在属性中找到method
  3. 查找代表用户名和密码的字段的 ID。

有了这些,您可以轻松构建一个模仿登录的 WebRequest。

请注意,这假设一个直接的登录屏幕(没有 AJAX,没有验证码)。

于 2013-07-25T22:55:59.210 回答