2011-09-22 19 views
6

Estoy intentando descargar los contenidos de un sitio web. Sin embargo, para una página web determinada, la cadena devuelta contiene datos confusos, que contienen muchos caracteres.C# Descargar el sitio web en cadena usando C# WebClient o HttpWebRequest

Aquí está el código que estaba usando originalmente.

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url); 
req.Method = "GET"; 
req.UserAgent = "Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))"; 
string source; 
using (StreamReader reader = new StreamReader(req.GetResponse().GetResponseStream())) 
{ 
    source = reader.ReadToEnd(); 
} 
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); 
doc.LoadHtml(source); 

También probé implementaciones alternativas con el cliente Web, pero sigue siendo el mismo resultado:

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); 
using (WebClient client = new WebClient()) 
using (var read = client.OpenRead(url)) 
{ 
    doc.Load(read, true); 
} 

partir de la búsqueda supongo que esto podría ser un problema con la codificación, así que intenté tanto las soluciones publican a continuación, pero aún no puedo hacer que esto funcione

El sitio infractor que me parece que no puede descargar es el artículo Estados_Unidos en la versión de Inglés de la Wikipedia (en. Wikipedia. Org/wiki/Estados_Unidos). Aunque he intentado varios otros artículos de wikipedia y no he visto este problema.

Respuesta

2

La respuesta está codificada gzip. Prueba lo siguiente para descodificar la secuencia:

ACTUALIZACIÓN

Basado en el comentario de BrokenGlass estableciendo las siguientes propiedades deben resolver su problema (que funcionó para mí):

req.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate"; 
req.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; 

Viejo/Solución manual:

string source; 
var response = req.GetResponse(); 

var stream = response.GetResponseStream(); 
try 
{ 
    if (response.Headers.AllKeys.Contains("Content-Encoding") 
     && response.Headers["Content-Encoding"].Contains("gzip")) 
    { 
     stream = new System.IO.Compression.GZipStream(stream, System.IO.Compression.CompressionMode.Decompress); 
    } 

    using (StreamReader reader = new StreamReader(stream)) 
    { 
     source = reader.ReadToEnd(); 
    } 
} 
finally 
{ 
    if (stream != null) 
     stream.Dispose(); 
} 
+1

Nunca debes hacer esto manualmente, esto ya está incorporado, es decir, mira esta respuesta : http://stackoverflow.com/questions/2973208/automatically-decompress-gzip-response-via-webclient-downloaddata – BrokenGlass

+0

@BrokenGlass Gracias por la pista. Ya me preguntaba por qué nunca tuve problemas con la codificación gzip antes. – Peter

+0

¡Gracias, esto funcionó para mí! – EnISeeK

3

El uso de la incorporada en el cargador en HtmlAgilityPack trabajó para mí:

HtmlWeb web = new HtmlWeb(); 
HtmlDocument doc = web.Load("http://en.wikipedia.org/wiki/United_States"); 
string html = doc.DocumentNode.OuterHtml; // I don't see no jumbled data here 

Editar:

El uso de un estándar WebClient con su agente de usuario dará lugar a un HTTP 403 - Prohibida - usando esta vez funcionó para mí:

using (WebClient wc = new WebClient()) 
{ 
    wc.Headers.Add("user-agent", "Mozilla/5.0 (Windows; Windows NT 5.1; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4"); 
    string html = wc.DownloadString("http://en.wikipedia.org/wiki/United_States"); 
    HtmlDocument doc = new HtmlDocument(); 
    doc.LoadHtml(html); 
} 

también ver este hilo SO: WebClient forbids opening wikipedia page?

+0

He intentado el primero hod sugirió y obtuvo el siguiente error: 'gzip' no es un nombre de codificación compatible. Nombre del parámetro: nombre en System.Globalization.EncodingTable.internalGetCodePageFromName (String name) en System.Globalization.EncodingTable.GetCodePageFromName (String name) – EnISeeK

+0

@Nick: Funcionó bien para mí - asegúrese de tener la última versión de HtmlAgilityPack - Obtuve el mío de NuGet – BrokenGlass

+0

Esto sigue fallando con el mismo error después de obtener HtmlAgilityPack de NuGet. La versión instalada por NuGet es 1.4.0.0. – EnISeeK

1

Esta es la forma por lo general me agarra una página en una cadena (su VB, pero debería traducirse fácilmente):

req = Net.WebRequest.Create("http://www.cnn.com") 
Dim resp As Net.HttpWebResponse = req.GetResponse() 
sr = New IO.StreamReader(resp.GetResponseStream()) 
lcResults = sr.ReadToEnd.ToString 

y no han tenido los problemas que está.

Cuestiones relacionadas