pertanyaan:
Saat alat perayapan web secara otomatis mengumpulkan informasi halaman, beberapa halaman tampak kacau. Alasannya adalah:
Jenis pengkodean yang salah digunakan untuk membaca informasi halaman. Informasi pengkodean yang diperoleh C#.NET dari kelas saat ini terkadang salah. Menurut saya untuk aplikasi yang bukan ASP.NET, informasi pengkodean yang dibacanya salah.
menyelesaikan:
Ide: Anda harus terlebih dahulu mendapatkan pengkodean halaman saat runtime, dan kemudian membaca konten halaman, sehingga konten halaman yang diperoleh tidak kacau.
metode:
1: Gunakan pengkodean ASCII untuk membaca konten halaman.
2: Gunakan ekspresi reguler untuk menyaring informasi pengkodean halaman dari konten halaman yang dibaca. Informasi halaman yang diperoleh pada langkah sebelumnya mungkin kacau. Namun markup HTML sudah benar, dan semua informasi yang dikodekan dapat diperoleh dari markup HTML.
3. Gunakan jenis pengkodean yang benar untuk membaca informasi halaman.
Jika ada yang punya metode yang lebih baik, mohon pencerahannya!
Kode terlampir di bawah ini:
Demonstrasi Kode
menggunakan Sistem;
menggunakan System.Collections.Generik;
menggunakan Sistem.Teks;
menggunakan System.Net;
menggunakan Sistem.Web;
menggunakan Sistem.IO;
menggunakan System.Text.RegularExpressions;
namespacecharset
{
Program kelas
{
kekosongan statis Utama (string[] args)
{
string url = " http://www.gdqy.edu.cn ";
DapatkanCharset1(url);
GetChartset2(url);
Konsol.Baca();
}
// Dapatkan pengkodean halaman secara langsung melalui HttpWebResponse
kekosongan statis GetCharset1 (string url)
{
mencoba
{
WebRequest webRequest = WebRequest.Buat(url);
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
rangkaian karakter string = webResponse.CharacterSet;
string contentEncoding = webResponse.ContentEncoding;
string contentType = webResponse.ContentType;
Console.WriteLine("tipe konteks:{0}", contentType);
Console.WriteLine("charset:{0}", charset
Console.WriteLine("pengkodean konten:{0}" , pengkodean konten);
//Uji atau ambil apakah halamannya kacau
//Konsol.WriteLine(getHTML(url,rangkaian karakter));
}
menangkap (UriFormatException ex)
{
Console.WriteLine(ex.Message);
}
menangkap (WebException ex)
{
Console.WriteLine(mis.Pesan);
}
}
//Gunakan ekspresi reguler untuk mendapatkan pengkodean halaman
kekosongan statis GetChartset2 (url string)
{
mencoba
{
string html = getHTML(url,Encoding.ASCII.EncodingName);
Regex reg_charset = Regex baru(@"charsetbs*=s*(?<charset>[^""]*)");
string yang dikodekan = null;
jika (reg_charset.IsMatch(html))
{
enconding = reg_charset.Match(html).Groups["charset"].Value;
Console.WriteLine("rangkaian karakter:{0}",enconding);
}
kalau tidak
{
enconding = Pengkodean.Default.Nama Pengkodean;
}
//Uji atau ambil apakah halamannya kacau
//Console.WriteLine(getHTML(url,enconding));
}
menangkap (UriFormatException ex)
{
Console.WriteLine(ex.Message);
}
menangkap (WebException ex)
{
Console.WriteLine(mis.Pesan);
}
}
//Baca metode konten halaman
string statis getHTML(url string,nama pengkodean string)
{
mencoba
{
WebRequest webRequest = WebRequest.Buat(url);
WebResponse webResponse = webRequest.GetResponse();
Aliran aliran = webResponse.GetResponseStream();
StreamReader sr = new StreamReader(stream, Encoding.GetEncoding(encodingName));
string html = sr.ReadToEnd();
kembalikan html;
}
menangkap (UriFormatException ex)
{
Console.WriteLine(ex.Message);
kembalikan nol;
}
menangkap (WebException ex)
{
Console.WriteLine(ex.Message);
kembalikan nol;
}
}
}
}
Format pengkodean yang digunakan pada halaman http://www.gdqy.edu.cn adalah: gb2312
Konten yang ditampilkan dengan metode pertama adalah:
tipe konteks:teks/html
rangkaian karakter: ISO-8859-1
pengkodean konten:
Konten yang ditampilkan dengan metode kedua adalah:
charset:gb2312
, sehingga informasi yang diperoleh pada cara pertama salah, dan cara kedua benar.
Mengapa format pengkodean diperoleh dengan metode pertama: ISO-8859-1?
Saya menggunakan alat refleksi Reflektor untuk mendapatkan kode sumber properti CharacterSet, dan tidak sulit untuk melihat alasannya. Jika kami bisa mendapatkan kode sumber atribut ContentType, kami akan dapat melihat penyebab kesalahannya, tetapi saya sudah lama tidak dapat menemukannya. Jika ada yang bisa memperbaikinya, saya akan melakukannya bersyukurlah.
Di bawah ini saya lampirkan tool refleksi Reflector untuk mendapatkan source code dari properti CharacterSet. Teman-teman yang berminat bisa melihatnya.
Kode sumber CharacterSet
Rangkaian Karakter string publik
{
mendapatkan
{
ini.PeriksaDisposisi();
string text1 = ini.m_HttpResponseHeaders.ContentType;
if ((ini.m_CharacterSet == null) && !ValidationHelper.IsBlankString(teks1))
{
this.m_CharacterSet = string.Kosong;
string text2 = text1.ToLower(CultureInfo.InvariantCulture);
if (teks2.Trim().StartsWith("teks/"))
{
this.m_CharacterSet = "ISO-8859-1";
}
int angka1 = teks2.IndexOf(";");
jika (angka1 > 0)
{
while ((angka1 = text2.IndexOf("rangkaian karakter", angka1)) >= 0)
{
angka1 += 7;
if ((teks2[angka1 - 8] == ';') || (teks2[angka1 - 8] == ' '))
{
while ((angka1 < teks2.Panjangnya) && (teks2[angka1] == ' '))
{
nomor1++;
}
if ((angka1 < (teks2.Panjang - 1)) && (teks2[angka1] == '='))
{
nomor1++;
int angka2 = text2.IndexOf(';', angka1);
jika (angka2 > angka1)
{
this.m_CharacterSet = teks1.Substring(angka1, angka2).Trim();
merusak;
}
this.m_CharacterSet = teks1.Substring(angka1).Trim();
merusak;
}
}
}
}
}
kembalikan ini.m_CharacterSet;
}
http://www.cnblogs.com/xuanfeng/archive/2007/01/21/626296.html