1

httpwerequests でフォーラムにログインしようとしていますが、これまでのところ成功していません。これが私のコードです:

string url = "http://www.warriorforum.com/";

var bytes = Encoding.Default.GetBytes(@"vb_login_username=MyUsername&cookieuser=1&vb_login_password=&s=&securitytoken=guest&do=login&vb_login_md5password=d9350bad28eee253951d7c5211e50179&vb_login_md5password_utf=d9350bad28eee253951d7c5211e50179");
var container = new CookieContainer();

var request = (HttpWebRequest)(WebRequest.Create(url));
request.CookieContainer = container;
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/535.2";
request.ContentLength = bytes.Length;
request.Method = "POST";
request.KeepAlive = true;
request.AllowAutoRedirect = true;
request.AllowWriteStreamBuffering = true;
request.CookieContainer = container;
using (var requestStream = request.GetRequestStream())
    requestStream.Write(bytes, 0, bytes.Length);

var requestResponse = request.GetResponse();
using (var responsStream = requestResponse.GetResponseStream())
{
    if (responsStream != null)
    {
        using (var responseReader = new StreamReader(responsStream))
        {
            var responseStreamReader = responseReader.ReadToEnd();
            richTextBox1.Text = responseStreamReader; //this is to read the page source after the request
        }
    }
}

要求の後、応答はまったく同じページであり、何も変更されておらず、間違ったパスワードを入力したことを知らせるメッセージなどもありません。

4

2 に答える 2

0

一般的な VBulletin ログイン関数を使用してテストしたところ、正常に動作するように見えました。

private static bool VBulletinLogin(Uri loginUrl, string user, string password)
{
    var postParams = new[] {
        new HttpParam("vb_login_username", user),
        new HttpParam("cookieuser", "1"),
        new HttpParam("vb_login_password", password),
        new HttpParam("securitytoken", "guest"),
        new HttpParam("do", "login"),
    };

    var http = new HttpContext();
    var src = http.GetEncodedPageData(loginUrl, HttpRequestType.POST, postParams);
    return src.ResponseData.Contains("Thank you for logging in");
}

残念ながら、これは私HttpContextが書いてきたライブラリの一部であり、機能がかなり絡み合っている私のクラスを使用しています。ただし、少なくとも投稿パラメーターのアイデアが得られることを願っています。また、役立つはずの独自のクラスからいくつかの役立つ構造体/関数を含めました。(注: .NET 3.5System.Web名前空間への参照が必要です。

最初の有用な構造体、HttpParam:

public struct HttpParam
{
    private string _key;
    private string _value;

    public string Key { get { return HttpUtilty.UrlEncode(_key); } set { _key = value; } }
    public string Value { get { return HttpUtility.UrlEncode(_value); } set { _value = value; } }

    public HttpParam(string key, string value)
    {
        _key = key;
        _value = value;
    }

    public override string ToString()
    {
        return string.Format("{0}={1}", Key, Value);
    }
};

それに付随する機能:

private static string GetQueryString(HttpParam[] args)
{
    return args != null
            ? string.Join("&", Array.ConvertAll(args, arg => arg.ToString()))
            : string.Empty;
}

これらを組み合わせることで、一貫性のある安全なクエリ文字列を生成できます。したがって、上記の場合:

var postParams = new[] {
    new HttpParam("vb_login_username", user),
    new HttpParam("cookieuser", "1"),
    new HttpParam("vb_login_password", password),
    new HttpParam("securitytoken", "guest"),
    new HttpParam("do", "login"),
};

var queryString = GetQueryString(postParams);

次のようなものが得られます:

vb_login_username=<user>&cookieuser=1&vb_login_password=<password>&securitytoken=guest&do=login

次に、投稿用に既に持っているものと同様のものを使用できますが、正しい URL があることを確認してください。UTF8クエリ文字列のバイトを取得するときにもエンコードを使用します。例(元のコードを少し変更して使用)

var postParams = new[] {
    new HttpParam("vb_login_username", "yourusername"),
    new HttpParam("cookieuser", "1"),
    new HttpParam("vb_login_password", "yourpassword"),
    new HttpParam("securitytoken", "guest"),
    new HttpParam("do", "login"),
};

string url = "http://warriorforum.com/login.php?do=login";
var container = new CookieContainer();
var buffer = Encoding.UTF8.GetBytes(GetQueryString(postParams));

var request = (HttpWebRequest)HttpWebRequest.Create(url);
request.CookieContainer = container;
request.UserAgent = "Mozilla/5.0";
request.Method = "POST";
request.KeepAlive = true;
request.AllowAutoRedirect = true;
request.CookieContainer = container;
request.ContentLength = buffer.Length;
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";

using (var requestStream = request.GetRequestStream())
    requestStream.Write(buffer, 0, buffer.Length);

using (var response = request.GetResponse())
{
    if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.NotModified)
    {
        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            var result = reader.ReadToEnd();
            richTextBox1.Text = result; //this is to read the page source after the request
        }
    }
}

の変更にも注意してくださいContentType

于 2012-11-04T11:30:55.250 に答える
0

ログイン時にブラウザが行う何かが欠けているようです...そのフォーラムは本当に必要ですPOSTGET? すべてのパラメータは正しいですか? ブラウザからのログイン時に、Web ページが追加パラメータ (非表示) を送信する可能性はありますか?

ブラウザ経由で手動でログインするときに実際にネットワーク上で何が行われるかを確認する必要があります。WiresharkまたはFiddlerを使用して、コードで何が起こるかを調べてシミュレートします...

于 2012-11-04T10:21:13.400 に答える