Frage:
Wenn das Web-Crawling-Tool automatisch Seiteninformationen sammelt, scheinen einige Seiten verstümmelt zu sein. Die Gründe dafür sind:
Zum Lesen der Seiteninformationen wurde der falsche Codierungstyp verwendet. Die Codierungsinformationen, die C#.NET von der aktuellen Klasse erhält, sind meiner Meinung nach manchmal falsch, wenn es sich um Anwendungen handelt, die nicht ASP.NET sind.
lösen:
Idee: Sie müssen zuerst die Codierung der Seite zur Laufzeit abrufen und dann den Inhalt der Seite lesen, damit der erhaltene Seiteninhalt nicht verstümmelt wird.
Verfahren:
1: Verwenden Sie die ASCII-Codierung, um den Seiteninhalt zu lesen.
2: Verwenden Sie reguläre Ausdrücke, um die Codierungsinformationen der Seite aus dem gelesenen Seiteninhalt herauszufiltern. Die im vorherigen Schritt erhaltenen Seiteninformationen sind möglicherweise verstümmelt. Das HTML-Markup ist jedoch korrekt und alle codierten Informationen können aus dem HTML-Markup abgerufen werden.
3. Verwenden Sie den richtigen Codierungstyp, um Seiteninformationen zu lesen.
Wenn jemand eine bessere Methode hat, klären Sie mich bitte auf!
Der Code ist unten angehängt:
Code-Demonstration
Verwenden des Systems;
mit System.Collections.Generic;
Verwenden von System.Text;
mit System.Net;
mit System.Web;
mit System.IO;
Verwenden von System.Text.RegularExpressions;
Namespacecharset
{
Klassenprogramm
{
static void Main(string[] args)
{
string url = " http://www.gdqy.edu.cn ";
GetCharset1(url);
GetChartset2(url);
Console.Read();
}
// Holen Sie sich die Seitenkodierung direkt über HttpWebResponse
static void GetCharset1(string url)
{
versuchen
{
WebRequest webRequest = WebRequest.Create(url);
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
string charset = webResponse.CharacterSet;
string contentEncoding = webResponse.ContentEncoding;
string contentType = webResponse.ContentType;
Console.WriteLine("context type:{0}", contentType
("charset:{0}", charset)
; , contentEncoding);
//Testen oder abrufen, ob die Seite verstümmelt ist
//Console.WriteLine(getHTML(url,charset));
}
Catch (UriFormatException ex)
{
Console.WriteLine(ex.Message);
}
Catch(WebException ex)
{
Console.WriteLine(ex.Message);
}
}
//Regulären Ausdruck verwenden, um die Seitenkodierung zu erhalten
static void GetChartset2(string url)
{
versuchen
{
string html = getHTML(url,Encoding.ASCII.EncodingName);
Regex reg_charset = new Regex(@"charsetbs*=s*(?<charset>[^""]*)");
string enconding = null;
if (reg_charset.IsMatch(html))
{
enconding = reg_charset.Match(html).Groups["charset"].Value;
Console.WriteLine("charset:{0}",enconding);
}
anders
{
enconding = Encoding.Default.EncodingName;
}
//Testen oder abrufen, ob die Seite verstümmelt ist
//Console.WriteLine(getHTML(url,enconding));
}
Catch (UriFormatException ex)
{
Console.WriteLine(ex.Message);
}
Catch(WebException ex)
{
Console.WriteLine(ex.Message);
}
}
//Seiteninhaltsmethode lesen
statischer String getHTML(String-URL,String-EncodingName)
{
versuchen
{
WebRequest webRequest = WebRequest.Create(url);
WebResponse webResponse = webRequest.GetResponse();
Stream stream = webResponse.GetResponseStream();
StreamReader sr = new StreamReader(stream, Encoding.GetEncoding(encodingName));
string html = sr.ReadToEnd();
html zurückgeben;
}
Catch (UriFormatException ex)
{
Console.WriteLine(ex.Message);
null zurückgeben;
}
Catch (WebException ex)
{
Console.WriteLine(ex.Message);
null zurückgeben;
}
}
}
}
Das auf der Seite http://www.gdqy.edu.cn verwendete Kodierungsformat ist: gb2312
Der von der ersten Methode angezeigte Inhalt ist:
Kontexttyp:text/html
Zeichensatz: ISO-8859-1
Inhaltskodierung:
Der von der zweiten Methode angezeigte Inhalt ist:
charset:gb2312
, daher sind die mit der ersten Methode erhaltenen Informationen falsch und mit der zweiten Methode korrekt.
Warum wird das Codierungsformat mit der ersten Methode erhalten: ISO-8859-1?
Ich habe das Reflector-Reflexionstool verwendet, um den Quellcode der CharacterSet-Eigenschaft abzurufen, und es ist nicht schwer, den Grund dafür zu erkennen. Wenn wir den Quellcode des ContentType-Attributs erhalten könnten, könnten wir die Ursache des Fehlers erkennen, aber ich konnte es nach langer Zeit nicht herausfinden. Wenn jemand das nachholen kann, würde ich es tun sei sehr dankbar.
Unten hänge ich das Reflector-Reflexionstool an, um den Quellcode der CharacterSet-Eigenschaft zu erhalten. Interessierte Freunde können einen Blick darauf werfen.
CharacterSet-Quellcode
öffentlicher String-Zeichensatz
{
erhalten
{
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("text/"))
{
this.m_CharacterSet = "ISO-8859-1";
}
int num1 = text2.IndexOf(";");
if (num1 > 0)
{
while ((num1 = text2.IndexOf("charset", num1)) >= 0)
{
num1 += 7;
if ((text2[num1 - 8] == ';') || (text2[num1 - 8] == ' '))
{
while ((num1 < text2.Length) && (text2[num1] == ' '))
{
num1++;
}
if ((num1 < (text2.Length - 1)) && (text2[num1] == '='))
{
num1++;
int num2 = text2.IndexOf(';', num1);
if (num2 > num1)
{
this.m_CharacterSet = text1.Substring(num1, num2).Trim();
brechen;
}
this.m_CharacterSet = text1.Substring(num1).Trim();
brechen;
}
}
}
}
}
return this.m_CharacterSet;
}
http://www.cnblogs.com/xuanfeng/archive/2007/01/21/626296.html