WebClient.DownloadString ()은 고유 한 문자가있는 곳을 반환합니다.
내가 만든 화면 스크래핑 도구를 위해 웹에서 다운로드하는 일부 콘텐츠에 문제가 있습니다.
아래 코드에서 웹 클라이언트 다운로드 절차에서 반환 된 코드는 일부 (전체가 아님) 웹 사이트에 대한 소스 다운로드에 대해 일부 이상한 문자를 반환합니다.
최근에 다음에 같이 http 헤더를 추가했습니다. 이전에는 동일한 효과를 헤더없이 동일한 코드가 호출되었습니다. 'Accept-Charset'헤더에 대한 변형을 시도하지 갑자기 및 기본 사항 외에 텍스트 인코딩에 대해 많이 알지 못합니다.
내가 언급하는 문자 또는 문자 시퀀스는 다음과 같다.
"  "
과
" Â "
모든 문자는 웹 브라우저에서 "소스보기"를 사용할 때 표시되지 않습니다. 이 문제의 원인은 무엇이며 어떻게 문제를 해결합니까?
string urlData = String.Empty;
WebClient wc = new WebClient();
// Add headers to impersonate a web browser. Some web sites
// will not respond correctly without these headers
wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12");
wc.Headers.Add("Accept", "*/*");
wc.Headers.Add("Accept-Language", "en-gb,en;q=0.5");
wc.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
urlData = wc.DownloadString(uri);

옥텟의 windows-1252 표현입니다 EF BB BF
. 이 UTF-8 바이트 순서 마커입니다 . 이는 마치 원격 웹 페이지가 UTF-8로 인코딩 마치 windows-1252 인 것처럼 읽고 있음을 의미합니다. 워드 프로세서에 따르면 , WebClient.DownloadString
사용 이 고도로 원격 리소스를 변환 할 때의 코딩한다. 로 설정하면 이론적으로 작동해야합니다.Webclient.Encoding
System.Text.Encoding.UTF8
WebClient.DownloadString
구현 방법 은 매우 멍청합니다. Content-Type
응답 의 헤더에서 문자 인코딩을 가져와야하지만 개발자가 예상되는 인코딩을 미리 알려줄 것입니다. 이 수업의 개발자들이 무슨 생각을했는지 모르겠습니다.
Content-Type
응답 헤더 에서 인코딩 이름을 검색하는 보조 클래스를 만들었습니다 .
public static class WebUtils
{
public static Encoding GetEncodingFrom(
NameValueCollection responseHeaders,
Encoding defaultEncoding = null)
{
if(responseHeaders == null)
throw new ArgumentNullException("responseHeaders");
//Note that key lookup is case-insensitive
var contentType = responseHeaders["Content-Type"];
if(contentType == null)
return defaultEncoding;
var contentTypeParts = contentType.Split(';');
if(contentTypeParts.Length <= 1)
return defaultEncoding;
var charsetPart =
contentTypeParts.Skip(1).FirstOrDefault(
p => p.TrimStart().StartsWith("charset", StringComparison.InvariantCultureIgnoreCase));
if(charsetPart == null)
return defaultEncoding;
var charsetPartParts = charsetPart.Split('=');
if(charsetPartParts.Length != 2)
return defaultEncoding;
var charsetName = charsetPartParts[1].Trim();
if(charsetName == "")
return defaultEncoding;
try
{
return Encoding.GetEncoding(charsetName);
}
catch(ArgumentException ex)
{
throw new UnknownEncodingException(
charsetName,
"The server returned data in an unknown encoding: " + charsetName,
ex);
}
}
}
( UnknownEncodingException
사용자 정의 구현 클래스에서 원하는 InvalidOperationException
경우 또는 자유롭게 구현하십시오 )
그런 다음 WebClient
클래스에 대한 다음 확장 메소드가 트릭을 수행합니다.
public static class WebClientExtensions
{
public static string DownloadStringAwareOfEncoding(this WebClient webClient, Uri uri)
{
var rawData = webClient.DownloadData(uri);
var encoding = WebUtils.GetEncodingFrom(webClient.ResponseHeaders, Encoding.UTF8);
return encoding.GetString(rawData);
}
}
따라서 귀하의 예에서 다음을 수행합니다.
urlData = wc.DownloadStringAwareOfEncoding(uri);
... 그리고 그게 다야.
var client = new WebClient { Encoding = System.Text.Encoding.UTF8 };
var json = client.DownloadString(url);
제 경우에는 사용자 에이전트와 쿠키를 제외하고 언어, 문자셋 수신 헤더를 삭제했습니다. 효과가 ..
// try commenting
//wc.Headers.Add("Accept-Language", "en-gb,en;q=0.5");
//wc.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
그들 중 어느 것도 "www.yahoo.com"과 같은 몇몇 특별한 웹 사이트에서 저를 위해 작동하지 않았습니다. 나는 내 문제를 해결하는 유일한 방법은 변화되었다 DownloadString
에 OpenRead
와 사용 UserAgent
예제 코드처럼 헤더를. 그러나 "www.varzesh3.com"과 같은 몇몇 사이트는 어떤 방법으로도 작동하지 않았습니다!
WebClient client = new WebClient()
client.Headers.Add(HttpRequestHeader.UserAgent, "");
var stream = client.OpenRead("http://www.yahoo.com");
StreamReader sr = new StreamReader(stream);
s = sr.ReadToEnd();
'ProgramingTip' 카테고리의 다른 글
VS Code 통합 터미널의 색상 테마 (0) | 2020.11.26 |
---|---|
DeprecationWarning : 펼쳐보기를 다른 서버로 실행할 때 보안 및 사용성 문제로 인해 Buffer ()가 더 이상 사용되지 않습니다. (0) | 2020.11.26 |
SQL Server 2008에 새 스키마를 추가하는 방법은 무엇입니까? (0) | 2020.11.26 |
Entity Framework Code First Fluent Api : 열에 강화 추가 (0) | 2020.11.26 |
변수가 한 노드 또는 다른 노드 같은지 확인하는 방법은 무엇입니까? (0) | 2020.11.26 |