web-dev-qa-db-ja.com

WebClientまたはWebRequestを使用してWebサイトにログインし、データにアクセスする

WebClient/WebRequestを使用して、Webサイト上の制限されたデータにアクセスしようとしています。そのWebサイトには公式のAPIはないので、私がやろうとしていることは、HTMLフォームに入力してサーバーに値を送信するだけなので、ログインします。

this および this を試しましたが、今後のリクエストがログインしているようには見えません。

私は明らかにWebClientを好むので、後者の例ははるかに魅力的ですが、レガシーのWebRequestは好むでしょう。

とにかく、最初の例ではログインしたと思いますが、プライベートデータにアクセスする今後のリクエストは、「This is member only content」というメッセージを含むページを返します。

WebClientを永続的にログインさせる方法は?

14
Shimmy

更新:

以下の my comment を参照してください。


これが私がやったことであり、動作します( credit )。

最初にこのクラスを追加します。

namespace System.Net
{
  using System.Collections.Specialized;
  using System.Linq;
  using System.Text;

  public class CookieAwareWebClient : WebClient
  {
    public void Login(string loginPageAddress, NameValueCollection loginData)
    {
      CookieContainer container;

      var request = (HttpWebRequest)WebRequest.Create(loginPageAddress);

      request.Method = "POST";
      request.ContentType = "application/x-www-form-urlencoded";

      var query = string.Join("&", 
        loginData.Cast<string>().Select(key => $"{key}={loginData[key]}"));

      var buffer = Encoding.ASCII.GetBytes(query);
      request.ContentLength = buffer.Length;
      var requestStream = request.GetRequestStream();
      requestStream.Write(buffer, 0, buffer.Length);
      requestStream.Close();

      container = request.CookieContainer = new CookieContainer();

      var response = request.GetResponse();
      response.Close();
      CookieContainer = container;
    }

    public CookieAwareWebClient(CookieContainer container)
    {
      CookieContainer = container;
    }

    public CookieAwareWebClient()
      : this(new CookieContainer())
    { }

    public CookieContainer CookieContainer { get; private set; }

    protected override WebRequest GetWebRequest(Uri address)
    {
      var request = (HttpWebRequest)base.GetWebRequest(address);
      request.CookieContainer = CookieContainer;
      return request;
    }
  }
}

使用法:

public static void Main()
{
  var loginAddress = "www.mywebsite.com/login";
  var loginData = new NameValueCollection
    {
      { "username", "shimmy" },
      { "password", "mypassword" }
    };

  var client = new CookieAwareWebClient();
  client.Login(loginAddress, loginData);
}
23
Shimmy

HTTPはステートレスです。そのため、WebClientを永続的にログインすることはできません。セッションの概念はHTTPには存在しません。 ASP.NETなどのサーバー側のテクノロジは、Cookieまたはすべての要求で送受信されるクエリ文字列パラメーターを使用して、セッションの概念を通じてステートフルな動作をシミュレートします。そうは言っても、ブラウザがWebClientから行うことをエミュレートすることは可能です。 Webサイトにアクセスできる場合は、適切な資格情報を使用してWebサイトに接続し、Fiddlerを使用してトラフィックをキャプチャします。次に、WebClientがブラウザとまったく同じ正しいCookie、リクエストヘッダー、クエリ文字列などを送信することを確認します。

5
Badri