سؤال:
عندما تقوم أداة الزحف على الويب بجمع معلومات الصفحة تلقائيًا، تظهر بعض الصفحات مشوهة، والأسباب هي:
تم استخدام نوع ترميز خاطئ لقراءة معلومات الصفحة. أحيانًا تكون معلومات التشفير التي يحصل عليها C#.NET من الفصل الحالي خاطئة، وأعتقد أنه بالنسبة للتطبيقات التي ليست من نوع ASP.NET، فإن معلومات التشفير التي يقرأها تكون خاطئة.
يحل:
الفكرة: يجب عليك أولاً الحصول على ترميز الصفحة في وقت التشغيل، ثم قراءة محتوى الصفحة، حتى لا يتم تشويه محتوى الصفحة الذي تم الحصول عليه.
طريقة:
1: استخدم ترميز ASCII لقراءة محتوى الصفحة.
2: استخدم التعبيرات العادية لتصفية معلومات ترميز الصفحة من محتوى الصفحة المقروءة. قد تكون معلومات الصفحة التي تم الحصول عليها في الخطوة السابقة مشوهة. لكن ترميز HTML صحيح، ويمكن الحصول على كافة المعلومات المشفرة من ترميز HTML.
3. استخدم نوع الترميز الصحيح لقراءة معلومات الصفحة.
إذا كان أي شخص لديه طريقة أفضل، يرجى تنويري لي!
الكود مرفق أدناه:
عرض الكود
باستخدام النظام؛
باستخدام System.Collections.Generic؛
باستخدام System.Text؛
باستخدام System.Net؛
باستخدام System.Web؛
باستخدام System.IO؛
باستخدام System.Text.RegularExpressions؛
namespacecharset
{
برنامج الصف
{
الفراغ الثابت الرئيسي (سلسلة [] الحجج)
{
عنوان URL للسلسلة = " http://www.gdqy.edu.cn ";
GetCharset1(url);
GetChartset2(url)
;
}
// احصل على ترميز الصفحة مباشرة من خلال HttpWebResponse
GetCharset1 باطل ثابت (عنوان url للسلسلة)
{
يحاول
{
WebRequest webRequest = WebRequest.Create(url);
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()
;
string contentEncoding = webResponse.ContentEncoding;
string contentType = webResponse.ContentType;
Console.WriteLine("context type:{0}", contentType);
Console.WriteLine("
charset:{0}", charset);
، ترميز المحتوى)؛
// اختبار أو استرداد ما إذا كانت الصفحة مشوهة
//Console.WriteLine(getHTML(url,charset));
}
قبض على (UriFormatException على سبيل المثال)
{
Console.WriteLine(ex.Message);
}
قبض على (WebException على سبيل المثال)
{
Console.WriteLine(ex.Message);
}
}
// استخدم التعبير العادي للحصول على ترميز الصفحة
GetChartset2 باطل ثابت (عنوان url للسلسلة)
{
يحاول
{
string 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 = Encoding.Default.EncodingName;
}
// اختبار أو استرداد ما إذا كانت الصفحة مشوهة
//Console.WriteLine(getHTML(url,enconding));
}
قبض على (UriFormatException على سبيل المثال)
{
Console.WriteLine(ex.Message);
}
قبض على (WebException على سبيل المثال)
{
Console.WriteLine(ex.Message);
}
}
// قراءة طريقة محتوى الصفحة
سلسلة ثابتة getHTML (عنوان url للسلسلة، اسم ترميز السلسلة)
{
يحاول
{
WebRequest webRequest = WebRequest.Create(url);
WebResponse webResponse = webRequest.GetResponse();
تيار الدفق = webResponse.GetResponseStream();
StreamReader sr = new StreamReader(stream, Encoding.GetEncoding(encodingName));
سلسلة html = sr.ReadToEnd();
إرجاع أتش تي أم أل؛
}
قبض على (UriFormatException على سبيل المثال)
{
Console.WriteLine(ex.Message);
عودة فارغة؛
}
قبض على (WebException على سبيل المثال)
{
Console.WriteLine(ex.Message);
عودة فارغة؛
}
}
}
}
تنسيق التشفير المستخدم في صفحة http://www.gdqy.edu.cn هو: gb2312
المحتوى المعروض بالطريقة الأولى هو:
نوع السياق: نص/أتش تي أم أل
مجموعة الأحرف: ISO-8859-1
ترميز المحتوى:
المحتوى المعروض بالطريقة الثانية هو:
charset:gb2312
، لذا فإن المعلومات التي تم الحصول عليها بواسطة الطريقة الأولى خاطئة والطريقة الثانية صحيحة.
لماذا يتم الحصول على تنسيق الترميز بالطريقة الأولى: ISO-8859-1؟
لقد استخدمت أداة الانعكاس للحصول على الكود المصدري لخاصية CharacterSet، وليس من الصعب معرفة السبب. إذا تمكنا من الحصول على الكود المصدري لسمة ContentType، فسنكون قادرين على معرفة سبب الخطأ، لكنني لم أتمكن من اكتشافه بعد فترة طويلة، إذا كان بإمكان شخص ما التعويض عنه، فسوف أفعل ذلك كن ممتنا جدا.
أرفق أدناه أداة الانعكاس للحصول على الكود المصدري لخاصية CharacterSet ويمكن للأصدقاء المهتمين إلقاء نظرة عليها.
كود مصدر مجموعة الأحرف
سلسلة الأحرف العامة
{
يحصل
{
this.CheckDispose();
string text1 = this.m_HttpResponseHeaders.ContentType;
إذا ((this.m_CharacterSet == null) && !ValidationHelper.IsBlankString(text1))
{
this.m_CharacterSet = string.Empty;
string text2 = text1.ToLower(CultureInfo.InvariantCulture);
إذا (text2.Trim().StartsWith("text/"))
{
this.m_CharacterSet = "ISO-8859-1";
}
int num1 = text2.IndexOf(";");
إذا (رقم1 > 0)
{
بينما ((num1 = text2.IndexOf("charset"، num1)) >= 0)
{
رقم1 += 7;
إذا ((text2[num1 - 8] == ';') || (text2[num1 - 8] == ' '))
{
بينما ((num1 < text2.Length) && (text2[num1] == ' '))
{
num1++;
}
إذا ((num1 < (text2.Length - 1)) && (text2[num1] == '='))
{
num1++;
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