Caracteres en cadena cambiados después de descargar HTML de Internet

Usando el siguiente código, puedo descargar el HTML de un archivo de internet:

WebClient wc = new WebClient(); // .... string downloadedFile = wc.DownloadString("http://www.myurl.com/"); 

Sin embargo, a veces el archivo contiene caracteres “interesantes” como é to é , to ↠y フシギダネ a フシギダム.

Creo que puede ser algo relacionado con diferentes tipos de Unicode o algo así, ya que cada personaje se cambia a 2 nuevos, tal vez cada personaje se divide por la mitad, pero tengo muy poco conocimiento en esta área. ¿Qué crees que está mal?

Aquí hay una clase de descarga envolvente que admite gzip y comprueba el encabezado de encoding y metatags para decodificarlo correctamente.

Crea una instancia de la clase y llama a GetPage() .

 public class HttpDownloader { private readonly string _referer; private readonly string _userAgent; public Encoding Encoding { get; set; } public WebHeaderCollection Headers { get; set; } public Uri Url { get; set; } public HttpDownloader(string url, string referer, string userAgent) { Encoding = Encoding.GetEncoding("ISO-8859-1"); Url = new Uri(url); // verify the uri _userAgent = userAgent; _referer = referer; } public string GetPage() { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); if (!string.IsNullOrEmpty(_referer)) request.Referer = _referer; if (!string.IsNullOrEmpty(_userAgent)) request.UserAgent = _userAgent; request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate"); using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { Headers = response.Headers; Url = response.ResponseUri; return ProcessContent(response); } } private string ProcessContent(HttpWebResponse response) { SetEncodingFromHeader(response); Stream s = response.GetResponseStream(); if (response.ContentEncoding.ToLower().Contains("gzip")) s = new GZipStream(s, CompressionMode.Decompress); else if (response.ContentEncoding.ToLower().Contains("deflate")) s = new DeflateStream(s, CompressionMode.Decompress); MemoryStream memStream = new MemoryStream(); int bytesRead; byte[] buffer = new byte[0x1000]; for (bytesRead = s.Read(buffer, 0, buffer.Length); bytesRead > 0; bytesRead = s.Read(buffer, 0, buffer.Length)) { memStream.Write(buffer, 0, bytesRead); } s.Close(); string html; memStream.Position = 0; using (StreamReader r = new StreamReader(memStream, Encoding)) { html = r.ReadToEnd().Trim(); html = CheckMetaCharSetAndReEncode(memStream, html); } return html; } private void SetEncodingFromHeader(HttpWebResponse response) { string charset = null; if (string.IsNullOrEmpty(response.CharacterSet)) { Match m = Regex.Match(response.ContentType, @";\s*charset\s*=\s*(?.*)", RegexOptions.IgnoreCase); if (m.Success) { charset = m.Groups["charset"].Value.Trim(new[] { '\'', '"' }); } } else { charset = response.CharacterSet; } if (!string.IsNullOrEmpty(charset)) { try { Encoding = Encoding.GetEncoding(charset); } catch (ArgumentException) { } } } private string CheckMetaCharSetAndReEncode(Stream memStream, string html) { Match m = new Regex(@"[A-Za-z0-9_-]+)""?", RegexOptions.Singleline | RegexOptions.IgnoreCase).Match(html); if (m.Success) { string charset = m.Groups["charset"].Value.ToLower() ?? "iso-8859-1"; if ((charset == "unicode") || (charset == "utf-16")) { charset = "utf-8"; } try { Encoding metaEncoding = Encoding.GetEncoding(charset); if (Encoding != metaEncoding) { memStream.Position = 0L; StreamReader recodeReader = new StreamReader(memStream, metaEncoding); html = recodeReader.ReadToEnd().Trim(); recodeReader.Close(); } } catch (ArgumentException) { } } return html; } } 

Como no puedo comentar (reputación insuficiente), tendré que publicar una respuesta adicional. Utilizo rutinariamente la gran clase de Mikael, pero encontré un problema práctico con la expresión regular que intenta encontrar la metainformación del juego de caracteres. Esta

 Match m = new Regex(@"[A-Za-z0-9_-]+)", RegexOptions.Singleline | RegexOptions.IgnoreCase).Match(html); 

falla en esto

  

mientras que esto

 Match m = new Regex(@"[A-Za-z0-9_-]+)""?", RegexOptions.Singleline | RegexOptions.IgnoreCase).Match(html); 

no.

Gracias, Mikael.

Prueba esto

 string downloadedFile = wc.DownloadString("http://www.myurl.com"); 

siempre elimino el último “Slash” y funcionó hasta ahora como un amuleto. Pero podría ser también un peligro