pergunta:
Quando a ferramenta de rastreamento da web coleta automaticamente informações da página, algumas páginas parecem distorcidas. Os motivos são:
O tipo de codificação incorreto foi usado para ler as informações da página. As informações de codificação que o C#.NET obtém da classe atual às vezes estão erradas. Acho que para aplicativos que não são ASP.NET, as informações de codificação que ele lê estão erradas.
resolver:
Idéia: você deve primeiro obter a codificação da página em tempo de execução e depois ler o conteúdo da página, para que o conteúdo da página obtido não fique distorcido.
método:
1: Use a codificação ASCII para ler o conteúdo da página.
2: Use expressões regulares para filtrar as informações de codificação da página do conteúdo da página lida. As informações da página obtidas na etapa anterior podem estar distorcidas. Mas a marcação HTML está correta e todas as informações codificadas podem ser obtidas na marcação HTML.
3. Use o tipo de codificação correto para ler as informações da página.
Se alguém tiver um método melhor, por favor me esclareça!
O código está anexado abaixo:
Demonstração de código
usando o sistema;
usando System.Collections.Generic;
usando System.Text;
usando System.Net;
usando System.Web;
usando System.IO;
usando System.Text.RegularExpressions;
namespacecharset
{
programa de aula
{
vazio estático principal(string[] args)
{
string url = " http://www.gdqy.edu.cn ";
GetCharset1(url);
GetChartset2(url);
Console.Read();
}
// Obtenha a codificação da página diretamente através do HttpWebResponse
vazio estático GetCharset1 (string url)
{
tentar
{
WebRequest webRequest = WebRequest.Create(url);
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()
;
string contentEncoding = webResponse.ContentEncoding;
string contentType = webResponse.ContentType;
Console.WriteLine("tipo de contexto:{0}", contentType
("charset:{0}", charset)
; , contentEncoding);
//Teste ou recupere se a página está ilegível
//Console.WriteLine(getHTML(url,charset));
}
pegar (UriFormatException ex)
{
Console.WriteLine(ex.Mensagem);
}
catch(WebException ex)
{
Console.WriteLine(ex.Mensagem);
}
}
//Use expressão regular para obter a codificação da página
vazio estático GetChartset2 (string url)
{
tentar
{
string html = getHTML(url,Encoding.ASCII.EncodingName);
Regex reg_charset = new Regex(@"charsetbs*=s*(?<charset>[^""]*)");
codificação de string = null;
se (reg_charset.IsMatch(html))
{
codificação = reg_charset.Match(html).Groups["charset"].Value;
Console.WriteLine("charset:{0}",enconding);
}
outro
{
codificação = Encoding.Default.EncodingName;
}
//Teste ou recupere se a página está ilegível
//Console.WriteLine(getHTML(url,enconding));
}
pegar (UriFormatException ex)
{
Console.WriteLine(ex.Mensagem);
}
catch(WebException ex)
{
Console.WriteLine(ex.Mensagem);
}
}
//Método de leitura do conteúdo da página
string estática getHTML(string url,string encodingName)
{
tentar
{
WebRequest webRequest = WebRequest.Create(url);
WebResponse webResponse = webRequest.GetResponse();
Fluxo de fluxo = webResponse.GetResponseStream();
StreamReader sr = novo StreamReader(stream, Encoding.GetEncoding(encodingName));
string html = sr.ReadToEnd();
retornar HTML;
}
pegar (UriFormatException ex)
{
Console.WriteLine(ex.Mensagem);
retornar nulo;
}
capturar (WebException ex)
{
Console.WriteLine(ex.Mensagem);
retornar nulo;
}
}
}
}
O formato de codificação usado na página http://www.gdqy.edu.cn é: gb2312
O conteúdo exibido pelo primeiro método é:
tipo de contexto:texto/html
conjunto de caracteres: ISO-8859-1
codificação de conteúdo:
O conteúdo exibido pelo segundo método é:
charset:gb2312
, portanto as informações obtidas pelo primeiro método estão erradas e o segundo método está correto.
Por que o formato de codificação é obtido pelo primeiro método: ISO-8859-1?
Usei a ferramenta de reflexão Reflector para obter o código-fonte da propriedade CharacterSet e não é difícil perceber o motivo. Se pudéssemos obter o código-fonte do atributo ContentType, poderíamos ver a causa do erro, mas não consegui descobrir depois de muito tempo. Se alguém puder compensar, eu o faria. fique muito grato.
Abaixo anexo a ferramenta de reflexão Reflector para obter o código fonte da propriedade CharacterSet. Amigos interessados podem dar uma olhada.
Código fonte do CharacterSet
string pública CharacterSet
{
pegar
{
this.CheckDisposed();
string text1 = this.m_HttpResponseHeaders.ContentType;
if ((this.m_CharacterSet == null) && !ValidationHelper.IsBlankString(text1))
{
this.m_CharacterSet = string.Empty;
string text2 = text1.ToLower(CultureInfo.InvariantCulture);
if (text2.Trim().StartsWith("texto/"))
{
this.m_CharacterSet = "ISO-8859-1";
}
int num1 = text2.IndexOf(";");
se (num1 > 0)
{
enquanto ((num1 = text2.IndexOf("conjunto de caracteres", num1)) >= 0)
{
num1 += 7;
if ((texto2[num1 - 8] == ';') || (texto2[num1 - 8] == ' '))
{
while ((num1 <text2.Length) && (text2[num1] == ' '))
{
num1++;
}
if ((num1 < (text2.Comprimento - 1)) && (text2[num1] == '='))
{
num1++;
int num2 = text2.IndexOf(';', num1);
se (num2 > num1)
{
this.m_CharacterSet = text1.Substring(num1, num2).Trim();
quebrar;
}
this.m_CharacterSet = text1.Substring(num1).Trim();
quebrar;
}
}
}
}
}
retorne este.m_CharacterSet;
}
http://www.cnblogs.com/xuanfeng/archive/2007/01/21/626296.html