question:
Lorsque l'outil d'exploration Web collecte automatiquement des informations sur les pages, certaines pages semblent tronquées. Les raisons sont les suivantes :
Un type de codage incorrect a été utilisé pour lire les informations de la page. Les informations de codage que C#.NET obtient de la classe actuelle sont parfois erronées. Je pense que pour les applications qui ne sont pas ASP.NET, les informations de codage qu'il lit sont fausses.
résoudre:
Idée : vous devez d'abord obtenir l'encodage de la page au moment de l'exécution, puis lire le contenu de la page, afin que le contenu de la page obtenu ne soit pas tronqué.
méthode:
1 : Utilisez le codage ASCII pour lire le contenu de la page.
2 : Utilisez des expressions régulières pour filtrer les informations de codage de la page du contenu de la page lue. Les informations de page obtenues à l’étape précédente peuvent être tronquées. Mais le balisage HTML est correct et toutes les informations codées peuvent être obtenues à partir du balisage HTML.
3. Utilisez le type de codage correct pour lire les informations de la page.
Si quelqu'un a une meilleure méthode, merci de m'éclairer !
Le code est joint ci-dessous :
Démonstration du code
utiliser le système ;
en utilisant System.Collections.Generic ;
en utilisant System.Text ;
en utilisant System.Net ;
en utilisant System.Web ;
en utilisant System.IO ;
en utilisant System.Text.RegularExpressions ;
jeu de caractères d'espace de noms
{
Programme de classe
{
static void Main(string[] arguments)
{
chaîne url = " http://www.gdqy.edu.cn " ;
GetCharset1(url);
GetChartset2(url);
Console.Read();
}
// Récupère l'encodage de la page directement via HttpWebResponse
vide statique GetCharset1 (URL de chaîne)
{
essayer
{
WebRequest webRequest = WebRequest.Create(url);
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
chaîne charset = webResponse.CharacterSet;
chaîne contentEncoding = webResponse.ContentEncoding ;
chaîne contentType = webResponse.ContentType;
Console.WriteLine("type de contexte :{0}", contentType);
Console.WriteLine("charset :{0}", charset
Console.WriteLine("encodage du contenu :{0}"); , contentEncoding);
//Test ou récupère si la page est tronquée
//Console.WriteLine(getHTML(url,charset));
}
attraper (UriFormatException ex)
{
Console.WriteLine(ex.Message);
}
catch (WebException ex)
{
Console.WriteLine(ex.Message);
}
}
//Utilisez une expression régulière pour obtenir l'encodage de la page
vide statique GetChartset2 (URL de chaîne)
{
essayer
{
chaîne html = getHTML(url,Encoding.ASCII.EncodingName);
Regex reg_charset = new Regex (@"charsetbs*=s*(?<charset>[^""]*)");
encodage de chaîne = null ;
si (reg_charset.IsMatch(html))
{
enconding = reg_charset.Match(html).Groups["charset"].Value;
Console.WriteLine("charset:{0}",enconding);
}
autre
{
encodage = Encoding.Default.EncodingName ;
}
//Test ou récupère si la page est tronquée
//Console.WriteLine(getHTML(url,enconding));
}
attraper (UriFormatException ex)
{
Console.WriteLine(ex.Message);
}
catch (WebException ex)
{
Console.WriteLine(ex.Message);
}
}
//Méthode de lecture du contenu de la page
chaîne statique getHTML (URL de chaîne, nom d'encodage de chaîne)
{
essayer
{
WebRequest webRequest = WebRequest.Create(url);
WebResponse webResponse = webRequest.GetResponse();
Stream stream = webResponse.GetResponseStream();
StreamReader sr = new StreamReader(stream, Encoding.GetEncoding(encodingName));
chaîne html = sr.ReadToEnd();
renvoyer du HTML ;
}
attraper (UriFormatException ex)
{
Console.WriteLine(ex.Message);
renvoie null ;
}
attraper (WebException ex)
{
Console.WriteLine(ex.Message);
renvoie null ;
}
}
}
}
Le format d'encodage utilisé sur la page http://www.gdqy.edu.cn est : gb2312
Le contenu affiché par la première méthode est :
type de contexte :texte/html
jeu de caractères : ISO-8859-1
encodage du contenu :
Le contenu affiché par la deuxième méthode est :
charset:gb2312
, donc les informations obtenues par la première méthode sont fausses et la deuxième méthode est correcte.
Pourquoi le format d'encodage obtenu par la première méthode : ISO-8859-1 ?
J'ai utilisé l'outil de réflexion Reflector pour obtenir le code source de la propriété CharacterSet, et il n'est pas difficile d'en voir la raison. Si nous pouvions obtenir le code source de l'attribut ContentType, nous serions en mesure de voir la cause de l'erreur, mais je n'ai pas pu la découvrir après un long moment. Si quelqu'un pouvait compenser, je le ferais. soyez très reconnaissant.
Ci-dessous, je joins l'outil de réflexion Reflector pour obtenir le code source de la propriété CharacterSet. Les amis intéressés peuvent y jeter un œil.
Code source du jeu de caractères
chaîne publique CharacterSet
{
obtenir
{
this.CheckDisposed();
string text1 = this.m_HttpResponseHeaders.ContentType ;
if ((this.m_CharacterSet == null) && !ValidationHelper.IsBlankString(text1))
{
this.m_CharacterSet = string.Empty;
chaîne text2 = text1.ToLower(CultureInfo.InvariantCulture);
si (text2.Trim().StartsWith("text/"))
{
this.m_CharacterSet = "ISO-8859-1" ;
}
int num1 = text2.IndexOf(";");
si (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);
si (num2 > num1)
{
this.m_CharacterSet = text1.Substring(num1, num2).Trim();
casser;
}
this.m_CharacterSet = text1.Substring(num1).Trim();
casser;
}
}
}
}
}
renvoie this.m_CharacterSet ;
}
http://www.cnblogs.com/xuanfeng/archive/2007/01/21/626296.html