83

私は C# を使用するのに比較的慣れておらず、Web サイトのソース コードの一部を読み取るアプリケーションを持っています。それはすべて機能します。しかし、問題は、問題のページにユーザーがログインしてこのソース コードにアクセスする必要があることです。私のプログラムには、最初にユーザーを Web サイトにログインさせる方法が必要です。それが完了すると、ソース コードにアクセスして読み取ることができるようになります。

ログインが必要な Web サイトは、mmoinn.com/index.do?PageModule=UsersLogin です。

これを行う方法について一日中検索し、例を試しましたが、うまくいきませんでした。

前もって感謝します

4

4 に答える 4

115

(現在 DownloadString で使用しているHTTP 動詞である GET の代わりに) WebClient を POST に引き続き使用できますが、(わずかに) 低レベルのクラス WebRequest および WebResponse を使用する方が簡単であることがわかると思います。

これには 2 つの部分があります。1 つ目はログイン フォームの送信、2 つ目は "Set-cookie" ヘッダーを回復し、それを "Cookie" として GET 要求と共にサーバーに送信することです。サーバーはこのCookieを使用して今後あなたを識別します(そのページが「PHPSESSID」を含むSet-cookieヘッダーを返すため、Cookieベースの認証を使用していると確信しています)。


ログインフォームへの投稿

フォーム投稿は簡単にシミュレートできます。投稿データを次のようにフォーマットするだけです。

field1=value1&field2=value2

Scott Hanselmanから改作した WebRequest とコードを使用して、フォーム データをログイン フォームに POST する方法は次のとおりです。

string formUrl = "http://www.mmoinn.com/index.do?PageModule=UsersAction&Action=UsersLogin"; // NOTE: This is the URL the form POSTs to, not the URL of the form (you can find this in the "action" attribute of the HTML's form tag
string formParams = string.Format("email_address={0}&password={1}", "your email", "your password");
string cookieHeader;
WebRequest req = WebRequest.Create(formUrl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
    os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];

ログイン フォームの Set-cookie ヘッダーに表示される内容の例を次に示します。

PHPSESSID=c4812cffcf2c45e0357a5a93c137642e; path=/; domain=.mmoinn.com,wowmine_referer=directenter; path=/; domain=.mmoinn.com,lang=en; path=/;domain=.mmoinn.com,adt_usertype=other,adt_host=-

ログインフォームの背後にあるページを取得する

これで、ログインが必要なページに対して GET リクエストを実行できます。

string pageSource;
string getUrl = "the url of the page behind the login";
WebRequest getRequest = WebRequest.Create(getUrl);
getRequest.Headers.Add("Cookie", cookieHeader);
WebResponse getResponse = getRequest.GetResponse();
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
    pageSource = sr.ReadToEnd();
}

編集:

最初の POST の結果を表示する必要がある場合は、返された HTML を次のように復元できます。

using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
    pageSource = sr.ReadToEnd();
}

これを直下に配置cookieHeader = resp.Headers["Set-cookie"];し、pageSource に保持されている文字列を調べます。

于 2009-05-31T01:33:03.947 に答える
39

WebClient から派生するクラスを作成し、その GetWebRequest メソッドをオーバーライドして、それに CookieContainer オブジェクトを設定することで、かなり単純化できます。常に同じ CookieContainer インスタンスを設定すると、Cookie の管理が自動的に処理されます。

ただし、送信前に HttpWebRequest を取得する唯一の方法は、WebClient から継承してそのメソッドをオーバーライドすることです。

public class CookieAwareWebClient : WebClient
{
    private CookieContainer cookie = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        if (request is HttpWebRequest)
        {
            (request as HttpWebRequest).CookieContainer = cookie;
        }
        return request;
    }
}

var client = new CookieAwareWebClient();
client.BaseAddress = @"https://www.site.com/any/base/url/";
var loginData = new NameValueCollection();
loginData.Add("login", "YourLogin");
loginData.Add("password", "YourPassword");
client.UploadValues("login.php", "POST", loginData);

//Now you are logged in and can request pages    
string htmlSource = client.DownloadString("index.php");
于 2009-06-23T08:31:29.840 に答える
9

Matthew Brindley さん、あなたのコードは必要な Web サイト (ログインあり) で非常にうまく機能しましたが、変更する必要がHttpWebRequestありましHttpWebResponseた。そうしないと、リモート サーバーから404 Bad Requestが返されます。また、あなたのコードを使用して回避策を共有したいと思います。moodle に基づいて Web サイトにログインしようとしましたログイン フォームの背後にあるページを取得する」というステップでは機能しませんでした。ログインすると、他のウェブサイトがそうするにもかかわらず、ヘッダーは何も返しませんでした。'Set-Cookie'

これは、次のリクエストのために Cookie を保存する必要がある場所だと思うので、これを追加しました。


ログイン フォームへの POSTing」コード ブロックに:

var cookies = new CookieContainer();
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl);
req.CookieContainer = cookies;


そして「ログインフォームの後ろのページを取得する」へ:

HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
getRequest.CookieContainer = new CookieContainer();
getRequest.CookieContainer.Add(resp.Cookies);
getRequest.Headers.Add("Cookie", cookieHeader);


これを行うと、ログインして「ログインの背後にあるページ」(Web サイトベースのCookieContainerムードル) のソース コードを取得できますリクエストをサーバーに送信します。とにかくこれは問題なく動作しますが、サンプル プロジェクトとチュートリアルについてWebRequest読むと良い情報があります。WebResponse

于 2011-12-10T05:01:02.497 に答える
2

ログイン要求とページ要求のAllowAutoRedirect両方をオフにして設定すると、同じユーザーエージェントが役立つ場合があります。POSTGET

request.UserAgent = userAgent;
request.AllowAutoRedirect = false;
于 2010-05-11T22:35:43.363 に答える