вопрос:
Когда инструмент веб-сканирования автоматически собирает информацию о страницах, некоторые страницы кажутся искаженными. Причины:
Для чтения информации о странице использовался неверный тип кодировки. Информация о кодировке, которую C#.NET получает от текущего класса, иногда неверна. Я думаю, что для приложений, отличных от ASP.NET, считываемая информация о кодировке неверна.
решать:
Идея: сначала необходимо получить кодировку страницы во время выполнения, а затем прочитать содержимое страницы, чтобы полученное содержимое страницы не было искажено.
метод:
1: использовать кодировку ASCII для чтения содержимого страницы.
2. Используйте регулярные выражения, чтобы отфильтровать информацию о кодировке страницы из прочитанного содержимого страницы. Информация о странице, полученная на предыдущем шаге, может быть искажена. Но разметка HTML правильная, и всю закодированную информацию можно получить из разметки HTML.
3. Используйте правильный тип кодировки для чтения информации о странице.
Если у кого-то есть лучший метод, пожалуйста, просветите меня!
Код прикреплен ниже:
Демонстрация кода.
использование системы;
использование System.Collections.Generic;
использование System.Text;
использование System.Net;
использование System.Web;
использование System.IO;
использование System.Text.RegularExpressions;
кодировка пространства имен
{
классная программа
{
static void Main(string[] args)
{
строка URL = " http://www.gdqy.edu.cn ";
GetCharset1 (URL);
GetChartset2(url);
Console.Read();
}
// Получаем кодировку страницы напрямую через HttpWebResponse
статическая пустота GetCharset1 (URL-адрес строки)
{
пытаться
{
WebRequest webRequest = WebRequest.Create(url);
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
набор символов строки = webResponse.CharacterSet;
строка contentEncoding = webResponse.ContentEncoding;
string contentType = webResponse.ContentType;
Console.WriteLine("тип контекста:{0}", contentType
Console.WriteLine("кодировка:{0}", charset);
Console.WriteLine("кодировка контента:{0}" , ContentEncoding);
//Проверяем или определяем, искажена ли страница
//Console.WriteLine(getHTML(url,charset));
}
поймать (UriFormatException ex)
{
Console.WriteLine(ex.Message);
}
улов (WebException ex)
{
Console.WriteLine(ex.Message);
}
}
//Используем регулярное выражение для получения кодировки страницы
статическая пустота GetChartset2 (URL-адрес строки)
{
пытаться
{
строка html = getHTML(url,Encoding.ASCII.EncodingName);
Regex reg_charset = new Regex(@"charsetbs*=s*(?<charset>[^""]*)");
окончание строки = ноль;
если (reg_charset.IsMatch(html))
{
enconding = reg_charset.Match(html).Groups["charset"].Value;
Console.WriteLine("кодировка:{0}",enconding);
}
еще
{
enconding = Кодировка.По умолчанию.ИмяКодировки;
}
//Проверяем или определяем, искажена ли страница
//Console.WriteLine(getHTML(url,enconding));
}
поймать (UriFormatException ex)
{
Console.WriteLine(ex.Message);
}
улов (WebException ex)
{
Console.WriteLine(ex.Message);
}
}
//Метод чтения содержимого страницы
статическая строка getHTML (URL-адрес строки, имя кодировки строки)
{
пытаться
{
WebRequest webRequest = WebRequest.Create(url);
WebResponse webResponse = webRequest.GetResponse();
Поток потока = webResponse.GetResponseStream();
StreamReader sr = новый StreamReader(поток, Encoding.GetEncoding(encodingName));
строка html = sr.ReadToEnd();
вернуть HTML;
}
поймать (UriFormatException ex)
{
Console.WriteLine(ex.Message);
вернуть ноль;
}
поймать (например, WebException)
{
Console.WriteLine(ex.Message);
вернуть ноль;
}
}
}
}
Формат кодировки, используемый на странице http://www.gdqy.edu.cn : gb2312.
Содержимое, отображаемое первым методом:
тип контекста: текст/html
кодировка: ISO-8859-1
кодировка контента:
Содержимое, отображаемое вторым методом:
charset:gb2312
, поэтому информация, полученная первым методом, неверна, а второй метод верен.
Почему формат кодировки получается первым способом: ISO-8859-1?
Я использовал инструмент отражения Reflector, чтобы получить исходный код свойства CharacterSet, и нетрудно понять причину. Если бы мы могли получить исходный код атрибута ContentType, мы смогли бы увидеть причину ошибки, но я не смог ее выяснить в течение долгого времени. Если кто-то может это исправить, я бы это сделал. будьте очень благодарны.
Ниже я прикрепляю инструмент отражения Reflector для получения исходного кода свойства CharacterSet. Друзья, которые заинтересованы, могут посмотреть.
Исходный код набора символов
общедоступная строка Набор символов
{
получать
{
это.CheckDispose();
строка text1 = this.m_HttpResponseHeaders.ContentType;
if ((this.m_CharacterSet == null) && !ValidationHelper.IsBlankString(text1))
{
this.m_CharacterSet = string.Empty;
строка text2 = text1.ToLower(CultureInfo.InvariantCulture);
если (text2.Trim().StartsWith("текст/"))
{
this.m_CharacterSet = "ISO-8859-1";
}
int num1 = text2.IndexOf(";");
если (число1 > 0)
{
while ((num1 = text2.IndexOf("кодировка", num1)) >= 0)
{
число1 += 7;
if ((text2[num1 - 8] == ';') || (text2[num1 - 8] == ' '))
{
while ((num1 < text2.Length) && (text2[num1] == ' '))
{
число1++;
}
if ((num1 < (text2.Length - 1)) && (text2[num1] == '='))
{
число1++;
int num2 = text2.IndexOf(';', num1);
если (число2 > число1)
{
this.m_CharacterSet = text1.Substring(num1, num2).Trim();
перерыв;
}
this.m_CharacterSet = text1.Substring(num1).Trim();
перерыв;
}
}
}
}
}
верните this.m_CharacterSet;
}
http://www.cnblogs.com/xuanfeng/archive/2007/01/21/626296.html