2009-12-20 3 views
3

방금 ​​컴퓨터에서 웹 크롤러가 작동하고 몇 분 안에 수천 개의 메타 태그 정보를 다운로드하는 것을 보았습니다.WebClient의 대안

WebClient를 사용하여 페이지를 다운로드 한 다음 로컬에서 구문 분석 할 때 WebClient가 단일 웹 페이지를 다운로드하는 데 약 40 초가 걸리는 이유는 무엇입니까? 웹 페이지를 다운로드 할 수있는 대안이 있습니까?

감사합니다 :)

+0

40초가 비정상적으로 길다. WebClient를 사용하여이 페이지를 다운로드하려면 300ms가 걸립니다. 뭔가 다른 일이 있습니다. –

+0

WebClient가 기본적으로 사용하는 사용자 에이전트 요청 헤더 문자열로 인해 사이트에서 제한이 발생할 수 있습니다. –

답변

6

몇 가지 고려해야 할

  • 얼마나 많은 페이지 당신은 한 번에 다운로드? 웹 크롤러는 매우 평행하게 작동하는 경향이 있습니다.
  • 기본적으로 .NET 프레임 워크는 병렬 요청 수를 단일 사이트로 제한합니다. 이는 일반적으로 좋은 일입니다. 한도를 조금 높이는 것이 좋지만 다른 사이트를 평행하게 타겟팅하는 것이 이상적입니다. 보고 싶은 요소는 <connectionManagement>입니다.
  • WireShark을 사용하여 네트워크 수준에서 어떤 현상이 발생했는지 확인하셨습니까? 웹 사이트가 페이지를 제공하는 데 40 초가 걸리면 WebClient를 사용하여 변경하면 어떻게 도움이되는지 알기가 어렵습니다.
  • 정확히 무엇을하고 있는지 보여줄 수있는 코드를 게시 할 수 있습니까?

그것은 다른 API를 (아마도 단지 WebRequest도) 일을 속도가 향상됩니다 사용 ,하지만 당신은 정말 먼저 현재 병목 현상을 찾아 낼 필요가있다.

+2

느린 원인을 알지 못하는 한 WebClient가 문제가 있다고 말하는 것은시기 상조입니다. –

1

는 성능 저하 얻을 수 있습니다 이유 몇 가지가 있습니다 : 비동기 방법/스레드의

  • 되지 않음 사용을
  • 불쌍한 HTML 구문 분석 알고리즘
  • 당신이 웹 클라이언트로 다운로드하는 페이지가 느린
  • 입니다

최종 답변을 찾으려면 자세한 정보/소스 코드가 필요합니다.

1

기본 프록시 인스턴스가있는 경우 Webclient가 느리게 작동하는 것과 관련된 게시물이 두 개 있습니다. MSDN Social에 이에 대한 세부 사항이 있습니다. Asyncronous 연결, 스레드 및 실제 소켓 코드를 작성하는 성능이 필요한 경우를 포함하여이를 더 빨리 수행하기 위해 수행해야 할 몇 가지 작업이 있습니다. 시장에 기본 프레임 워크 라이브러리보다 높은 기능을 제공하는 라이브러리가 있습니다. 추가 비용을 지불하려는 경우 이점이 있습니다.

Webrequest (기본 웹 클라이언트가 아님)를 사용하는 몇 가지 프로그램이 있으며 전 세계 절반에서 오는 10-20MB 범위의 리소스로 거의 MB/s 범위의 처리량을 볼 수 있습니다. 따라서 프레임 워크가 기본적으로 가능합니다.

2

거의 확실하게 게시 된 정보를 통해 쉽게 발견 할 수없는 코드에 또 다른 문제가 있습니다.

반면에 C# 크롤러를 만들 때 WebRequest/WebClient API는 CPU 사용량이 매우 높고 결국 크롤링에 적합하지 않음을 알게되었습니다. 결국 우리는 Socket.XxxxAsync 메소드를 사용하여 HTTP 스택을 작성하여 CPU로드를 약 20 배 줄였습니다. 이 길을 추구 할 때 꽤 가파른 학습 곡선이 있음을주의하십시오.

+0

그것이 CPU 병목 현상 이었습니까? 질문을 감안할 때 개발자가 하나의 페이지만으로 테스트를 수행했지만 병목 현상이 여전히 발생했다면 느린로드 페이지 또는 시간 초과라고 말할 수 있습니다. 어느 쪽이든 길기를 좋아하는 것 같습니다. –

0

크롤링 중 속도가 느려지면 이러한 설정이 도움이 될 수 있습니다.

ServicePointManager.DefaultConnectionLimit = int.MaxValue; 
ServicePointManager.MaxServicePoints = int.MaxValue; 
ServicePointManager.MaxServicePointIdleTime = 0; 

또한 레벨을 올리면 HttpWebRequest를 닫는 것을 잊지 마십시오.

HttpWebResponse.Close(); 
HttpWebResponse.GetResponseStream().Close(); 
HttpWebResponse.GetResponseStream().Dispose(); 

마이크