質問:
Web クローリング ツールがページ情報を自動的に収集すると、一部のページが文字化けして表示されます。その理由は次のとおりです。
ページ情報の読み取りに間違ったエンコード タイプが使用されました。 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)
;
}
// HttpWebResponse を通じてページのエンコーディングを直接取得します
静的 void 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}") 、コンテンツエンコーディング);
//ページが文字化けしているかどうかをテストまたは取得します
//Console.WriteLine(getHTML(url,charset));
}
catch (UriFormatException ex)
{
Console.WriteLine(ex.Message);
}
catch(WebException ex)
{
Console.WriteLine(例:メッセージ);
}
}
//正規表現を使用してページのエンコーディングを取得します
static void GetChartset2(string url)
{
試す
{
文字列 html = getHTML(url,Encoding.ASCII.EncodingName);
Regex reg_charset = new Regex(@"charsetbs*=s*(?
文字列エンコード = null;
if (reg_charset.IsMatch(html))
{
enconding = reg_charset.Match(html).Groups["charset"].Value;
Console.WriteLine("charset:{0}",enconding);
}
それ以外
{
enconding = エンコーディング.デフォルト.エンコーディング名;
}
//ページが文字化けしているかどうかをテストまたは取得します
//Console.WriteLine(getHTML(url,enconding));
}
catch (UriFormatException ex)
{
Console.WriteLine(ex.Message);
}
catch(WebException ex)
{
Console.WriteLine(例:メッセージ);
}
}
//ページコンテンツの読み込みメソッド
静的文字列 getHTML(文字列 URL,文字列エンコード名)
{
試す
{
WebRequest webRequest = WebRequest.Create(url);
WebResponse webResponse = webRequest.GetResponse();
ストリーム ストリーム = webResponse.GetResponseStream();
StreamReader sr = new StreamReader(stream, Encoding.GetEncoding(encodingName));
文字列 html = sr.ReadToEnd();
HTMLを返します。
}
catch (UriFormatException ex)
{
Console.WriteLine(ex.Message);
null を返します。
}
catch (WebException 例)
{
Console.WriteLine(ex.Message);
null を返します。
}
}
}
http://www.gdqy.edu.cnページで使用されるエンコード形式は gb2312 です
。
最初の方法で表示される内容は次のとおりです。
コンテキストタイプ:テキスト/html
文字セット:ISO-8859-1
コンテンツのエンコード:
2 番目の方法で表示される内容は次のとおりです。
charset:gb2312 である
ため、最初の方法で取得した情報は間違っており、2 番目の方法は正しいです。
エンコード形式が最初の方法 ISO-8859-1 で取得されるのはなぜですか?
CharacterSet プロパティのソース コードを取得するために Reflector リフレクション ツールを使用しましたが、その理由を理解するのは難しくありません。 ContentType 属性のソースコードを取得できれば、エラーの原因がわかるのですが、長い間調べてもわかりませんでした。誰かが補ってくれるなら、私はそうします。とても感謝してください。
以下に、CharacterSet プロパティのソース コードを取得するための Reflector 反射ツールを添付します。興味のある方はご覧ください。
CharacterSet のソースコード
パブリック文字列の文字セット
{
得る
{
this.CheckDisused();
文字列 text1 = this.m_HttpResponseHeaders.ContentType;
if ((this.m_CharacterSet == null) && !ValidationHelper.IsBlankString(text1))
{
this.m_CharacterSet = string.Empty;
文字列 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();
壊す;
}
this.m_CharacterSet = text1.Substring(num1).Trim();
壊す;
}
}
}
}
}
this.m_CharacterSet を返します。
http://www.cnblogs.com/xuanfeng/archive/2007/01/21/626296.html