web-dev-qa-db-fra.com

Utilisation de WebClient ou WebRequest pour vous connecter à un site Web et accéder aux données

J'essaie d'accéder à des données restreintes sur un site Web à l'aide de WebClient/WebRequest. Il n'y a pas d'API officielle sur ce site Web, donc ce que j'essaie de faire est simplement de remplir le formulaire HTML et de publier les valeurs sur le serveur, donc je suis connecté.

J'ai essayé this et this , mais il ne semble pas que les demandes à venir soient connectées.

Ce dernier exemple est beaucoup plus attrayant car je préfère évidemment WebClient, mais l'héritage WebRequest fera l'affaire.

Quoi qu'il en soit, dans le premier exemple, je pense qu'il s'est connecté, mais les demandes à venir qui accèdent aux données privées renvoient une page avec un message "Ceci est uniquement du contenu réservé aux membres".

Comment connecter un WebClient de façon permanente?

14
Shimmy

Mise à jour:

Voir mon commentaire ci-dessous.


Voici ce que j'ai fait et ça marche ( crédit ).

Ajoutez d'abord cette classe:

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;
    }
  }
}

Usage:

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 est sans état. Vous ne pouvez donc pas vous connecter de façon permanente à WebClient. Le concept de session n'existe pas dans HTTP. Les technologies côté serveur telles qu'ASP.NET simulent un comportement dynamique avec le concept de session utilisant un cookie ou un paramètre de chaîne de requête qui est envoyé dans les deux sens à chaque demande. Cela dit, il est possible d'émuler ce que fait un navigateur à partir de WebClient. Si vous avez accès au site Web, connectez-vous à celui-ci à l'aide des informations d'identification appropriées et capturez le trafic à l'aide de Fiddler. Ensuite, assurez-vous que WebClient envoie les bons cookies, les en-têtes de demande, les chaînes de requête, etc. exactement comme le navigateur.

5
Badri