Je suis relativement nouveau à l’utilisation de C # et dispose d’une application qui lit des parties du code source sur un site Web. Tout cela fonctionne mais le problème est que la page en question nécessite que l'utilisateur soit connecté pour accéder à ce code source. Ce que mon programme a besoin d’un moyen de connecter initialement l’utilisateur au site Web. Après cela, je pourrai accéder au code source et le lire.
Le site Web devant être connecté est: mmoinn.com/index.do?PageModule=UsersLogin
Toute la journée, j'ai cherché comment faire cela et essayé des exemples, mais je n'ai pas eu de chance.
Merci d'avance
Vous pouvez continuer à utiliser WebClient pour POST (au lieu de GET, qui est le verbe HTTP que vous utilisez actuellement avec DownloadString)), mais je pense que vous le trouverez. plus facile de travailler avec les classes (légèrement) de niveau inférieur WebRequest et WebResponse.
Cela comporte deux parties - la première consiste à publier le formulaire de connexion, la seconde consiste à récupérer l’en-tête "Set-cookie" et à le renvoyer au serveur sous forme de "Cookie" avec votre demande GET. Le serveur utilisera ce cookie pour vous identifier à partir de maintenant (en supposant qu'il utilise une authentification basée sur un cookie, ce dont je suis assez convaincu, car cette page renvoie un en-tête Set-cookie incluant "PHPSESSID").
POST au formulaire de connexion
Les publications sur formulaire sont faciles à simuler. Il vous suffit de formater vos données de publication de la manière suivante:
field1=value1&field2=value2
En utilisant WebRequest et le code que j'ai adapté de Scott Hanselman , voici comment vous auriez POST données de formulaire pour votre formulaire de connexion:
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"];
Voici un exemple de ce que vous devriez voir dans l'en-tête Set-cookie de votre formulaire de connexion:
PHPSESSID=c4812cffcf2c45e0357a5a93c137642e; path=/; domain=.mmoinn.com,wowmine_referer=directenter; path=/; domain=.mmoinn.com,lang=en; path=/;domain=.mmoinn.com,adt_usertype=other,adt_Host=-
Obtient la page derrière le formulaire de connexion
Vous pouvez maintenant effectuer votre requête GET sur une page pour laquelle vous devez être connecté.
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();
}
EDIT:
Si vous avez besoin d'afficher les résultats du premier POST, vous pouvez récupérer le code HTML renvoyé avec:
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
pageSource = sr.ReadToEnd();
}
Placez ceci directement en dessous de cookieHeader = resp.Headers["Set-cookie"];
puis inspectez la chaîne contenue dans pageSource.
Vous pouvez simplifier un peu les choses en créant une classe dérivée de WebClient, en remplaçant sa méthode GetWebRequest et en définissant un objet CookieContainer. Si vous définissez toujours la même instance CookieContainer, la gestion des cookies sera gérée automatiquement pour vous.
Mais le seul moyen d'obtenir l'accès à HttpWebRequest avant son envoi est d'hériter de WebClient et de remplacer cette méthode.
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");
Matthew Brindley , votre code a très bien fonctionné pour certains sites Web dont j'avais besoin (avec un identifiant), mais je devais passer à HttpWebRequest
et HttpWebResponse
sinon je reçois un 404 Requête incorrecte du serveur distant. Aussi, j'aimerais partager ma solution de contournement en utilisant votre code. Je l’ai essayé de me connecter à un site Web basé sur moodle, mais cela n’a pas fonctionné à votre étape " Obtention de la page derrière le formulaire de connexion "car avec succès POSTing la connexion, l'en-tête 'Set-Cookie'
n'a rien retourné malgré d'autres sites Web.
Je pense donc que nous devons stocker des cookies pour les prochaines demandes, alors j’ai ajouté ceci.
Pour le bloc de code " POST au formulaire de connexion ":
var cookies = new CookieContainer();
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl);
req.CookieContainer = cookies;
Et pour le " OBTENIR la page derrière le formulaire de connexion ":
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
getRequest.CookieContainer = new CookieContainer();
getRequest.CookieContainer.Add(resp.Cookies);
getRequest.Headers.Add("Cookie", cookieHeader);
Cela me permet Connectez-vous et obtenez le code source de la "page située derrière le login" (site Web moodle). Je sais que ceci est une utilisation vague du CookieContainer
et HTTPCookies car nous pouvons demander d’abord si un jeu de cookies a été enregistré avant d’envoyer la demande au serveur. Cela fonctionne sans problème, mais voici une bonne information à lire sur WebRequest
et WebResponse
avec des exemples de projets et un tutoriel:
Récupération du contenu HTTP dans .NET
Comment utiliser HttpWebRequest et HttpWebResponse dans .NET
Parfois, il peut être utile de désactiver AllowAutoRedirect
et de définir à la fois le login POST
et la page GET
pour demander le même agent utilisateur.
request.UserAgent = userAgent;
request.AllowAutoRedirect = false;