¿Cómo pasar las cookies a HtmlAgilityPack o WebClient?

c# cookies html-agility-pack httpwebrequest webclient

Pregunta

Yo uso este código para iniciar sesión:

CookieCollection cookies = new CookieCollection();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("example.com");
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
cookies = response.Cookies;

string getUrl = "example.com";
string postData = String.Format("my parameters");
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
getRequest.CookieContainer = new CookieContainer();
getRequest.CookieContainer.Add(cookies);
getRequest.Method = WebRequestMethods.Http.Post;
getRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0";
getRequest.AllowWriteStreamBuffering = true;
getRequest.ProtocolVersion = HttpVersion.Version11;
getRequest.AllowAutoRedirect = true;
getRequest.ContentType = "application/x-www-form-urlencoded";

byte[] byteArray = Encoding.ASCII.GetBytes(postData);
getRequest.ContentLength = byteArray.Length;
Stream newStream = getRequest.GetRequestStream();
newStream.Write(byteArray, 0, byteArray.Length);
newStream.Close();

HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse();
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream(), Encoding.GetEncoding("windows-1251")))
{
        doc.LoadHtml(sr.ReadToEnd());
        webBrowser1.DocumentText = doc.DocumentNode.OuterHtml;
}

luego quiero usar HtmlWeb (HtmlAgilityPack) o Webclient para analizar el HTML a HtmlDocument (HtmlAgilityPack).

Mi problema es que cuando uso:

WebClient wc = new WebClient();
webBrowser1.DocumentText = wc.DownloadString(site);

o

doc = web.Load(site);
webBrowser1.DocumentText = doc.DocumentNode.OuterHtml;

El inicio de sesión desaparece, así que creo que de alguna manera debo pasar las cookies ... ¿Alguna sugerencia?

Respuesta aceptada

Compruebe HtmlAgilityPack.HtmlDocument Cookies

Este es un ejemplo de lo que está buscando (sintaxis no probada al 100%, solo modifiqué algunas clases que suelo usar) :

public class MyWebClient
{
    //The cookies will be here.
    private CookieContainer _cookies = new CookieContainer();

    //In case you need to clear the cookies
    public void ClearCookies() {
        _cookies = new CookieContainer();
    }

    public HtmlDocument GetPage(string url) {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "GET";

        //Set more parameters here...
        //...

        //This is the important part.
        request.CookieContainer = _cookies;

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        var stream = response.GetResponseStream();

        //When you get the response from the website, the cookies will be stored
        //automatically in "_cookies".

        using (var reader = new StreamReader(stream)) {
            string html = reader.ReadToEnd();
            var doc = new HtmlDocument();
            doc.LoadHtml(html);
            return doc;
        }
    }
}

Así es como lo usas:

var client = new MyWebClient();
HtmlDocument doc = client.GetPage("http://somepage.com");

//This request will be sent with the cookies obtained from the page
doc = client.GetPage("http://somepage.com/another-page");

Nota: Si también desea utilizar el método POST , simplemente cree un método similar a GetPage con la lógica POST , refactorice la clase, etc.


Respuesta popular

Aquí hay algunas recomendaciones: Uso de CookieContainer con la clase WebClient

Sin embargo, es probable que sea más fácil seguir usando HttpWebRequest y configurar la cookie en el CookieContainer :

El código se ve algo como esto:

 // Create a HttpWebRequest
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(getUrl);

// Create the cookie container and add a cookie
request.CookieContainer = new CookieContainer();

// Add all the cookies
foreach (Cookie cookie in response.Cookies)
{
    request.CookieContainer.Add(cookie);
}

Lo segundo es que no necesita volver a descargar el sitio, ya que ya lo tiene en su respuesta web y lo está guardando aquí:

HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse();
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream(), Encoding.GetEncoding("windows-1251")))
{
        webBrowser1.DocumentText = doc.DocumentNode.OuterHtml;
}

Debería poder tomar el HTML y analizarlo con el Paquete de agilidad de HTML:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(webBrowser1.DocumentText);

Y eso debería hacerlo ... :)



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué