질문:
웹 크롤링 도구가 자동으로 페이지 정보를 수집할 때 일부 페이지가 깨져 보이는 경우가 있습니다. 이유는 다음과 같습니다.
페이지 정보를 읽는 데 잘못된 인코딩 유형이 사용되었습니다. C#.NET이 현재 클래스에서 얻는 인코딩 정보가 잘못된 경우가 있습니다. ASP.NET이 아닌 응용 프로그램의 경우 읽는 인코딩 정보가 잘못된 것 같습니다.
해결하다:
아이디어: 먼저 런타임 시 페이지 인코딩을 얻은 다음 페이지 내용을 읽어야 합니다. 그러면 얻은 페이지 내용이 왜곡되지 않습니다.
방법:
1: ASCII 인코딩을 사용하여 페이지 내용을 읽습니다.
2: 정규식을 사용하여 읽은 페이지 콘텐츠에서 페이지의 인코딩 정보를 필터링합니다. 이전 단계에서 얻은 페이지 정보가 왜곡될 수 있습니다. 그러나 HTML 마크업은 정확하며 인코딩된 모든 정보는 HTML 마크업에서 얻을 수 있습니다.
3. 페이지 정보를 읽으려면 올바른 인코딩 유형을 사용하십시오.
누구든지 더 좋은 방법이 있다면 알려주세요!
코드는 아래에 첨부되어 있습니다.
코드 데모
시스템 사용;
System.Collections.Generic을 사용합니다.
System.Text 사용;
System.Net 사용;
System.Web 사용;
System.IO 사용;
System.Text.RegularExpressions 사용;
네임스페이스 문자 집합
{
수업 프로그램
{
정적 무효 Main(string[] args)
{
문자열 url = " http://www.gdqy.edu.cn ";
GetCharset1(url);
GetChartset2(url);
Console.Read();
}
// HttpWebResponse를 통해 직접 페이지 인코딩을 가져옵니다.
정적 무효 GetCharset1(문자열 URL)
{
노력하다
{
WebRequest webRequest = WebRequest.Create(url);
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()
문자열 charset = webResponse.CharacterSet;
문자열 contentEncoding = webResponse.ContentEncoding;
string contentType = webResponse.ContentType;
Console.WriteLine("컨텍스트 유형:{0}", contentType)
Console.WriteLine(
"charset:{0}", charset);
, contentEncoding);
//페이지가 깨졌는지 테스트하거나 검색합니다.
//Console.WriteLine(getHTML(url,charset));
}
잡기(UriFormatException ex)
{
Console.WriteLine(ex.메시지);
}
catch(WebException ex)
{
Console.WriteLine(ex.Message);
}
}
//정규식을 사용하여 페이지 인코딩 가져오기
정적 무효 GetChartset2(문자열 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("문자 집합:{0}",enconding);
}
또 다른
{
enconding = Encoding.Default.EncodingName;
}
//페이지가 깨졌는지 테스트하거나 검색합니다.
//Console.WriteLine(getHTML(url,enconding));
}
잡기(UriFormatException ex)
{
Console.WriteLine(ex.메시지);
}
catch(WebException ex)
{
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();
HTML을 반환;
}
잡기(UriFormatException ex)
{
Console.WriteLine(ex.메시지);
null을 반환;
}
잡기(WebException 예)
{
Console.WriteLine(ex.메시지);
null을 반환;
}
}
}
}
http://www.gdqy.edu.cn 페이지에서 사용되는 인코딩 형식은 gb2312입니다.
첫 번째 방법으로 표시되는 내용은 다음과 같습니다.
컨텍스트 유형:텍스트/html
문자 집합:ISO-8859-1
콘텐츠 인코딩:
두 번째 방법으로 표시되는 내용은 다음과 같습니다.
charset:gb2312
이므로 첫 번째 방법으로 얻은 정보는 틀리고 두 번째 방법으로 얻은 정보는 정확합니다.
첫 번째 방법인 ISO-8859-1로 인코딩 형식을 얻는 이유는 무엇입니까?
CharacterSet 속성의 소스코드를 얻기 위해 Reflector 리플렉션 툴을 사용했는데, 그 이유는 어렵지 않게 알 수 있습니다. ContentType 속성의 소스 코드를 얻을 수 있다면 오류의 원인을 알 수 있겠지만, 오랜 시간이 지나도 알 수 없었을 것입니다. 매우 감사하십시오.
아래에는 CharacterSet 속성의 소스 코드를 얻기 위한 Reflector 반사 도구를 첨부합니다. 관심 있는 친구는 살펴보세요.
CharacterSet 소스 코드
공개 문자열 CharacterSet
{
얻다
{
this.CheckDisposed();
문자열 텍스트1 = this.m_HttpResponseHeaders.ContentType;
if ((this.m_CharacterSet == null) && !ValidationHelper.IsBlankString(text1))
{
this.m_CharacterSet = 문자열.비어있음;
string text2 = text1.ToLower(CultureInfo.InvariantCulture);
if (text2.Trim().StartsWith("text/"))
{
this.m_CharacterSet = "ISO-8859-1";
}
int num1 = text2.IndexOf(";");
만약 (숫자1 > 0)
{
while ((num1 = text2.IndexOf("charset", num1)) >= 0)
{
숫자1 += 7;
if ((텍스트2[숫자1 - 8] == ';') || (텍스트2[숫자1 - 8] == ' '))
{
while ((num1 < text2.Length) && (text2[num1] == ' '))
{
숫자1++;
}
if ((숫자1 < (text2.Length - 1)) && (text2[num1] == '='))
{
숫자1++;
int num2 = text2.IndexOf(';', num1);
if (숫자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