2013-04-23 6 views
1

나는 내 개인적인 용도로 C#에서 웹 크롤러를 쓰고있다. 크롤링하는 웹 페이지에서 이미지를 다운로드하는 것이 주 목적입니다. 다운로드 한 이미지 이외에는 웹 페이지의 데이터를 저장하지 않습니다.웹 크롤러가 방문한 URL을 저장하기위한 적절한 데이터 구조는 무엇입니까?

크롤러가 방문한 모든 URL의 리터럴 문자열을 목록에 저장하는 로직이 있습니다. 이것은 짧은 크롤링 세션에는 충분하지만 크롤러가 수만 개의 URL로 채워진 목록에서 조회를 수행 할 때 이것이 더 긴 세션에서 병목 현상이되기 시작할 것이라고 상상합니다. 또한 내 URL 대기열에서 조회를 수행하므로 크롤링 대기중인 대기열에 중복 된 URL이 없습니다.

1) 지금은 괜찮 내가 크롤링 세션 사이의 데이터를 저장하고 있지 않다 순간에서 :

내 질문은 두 부분이다. 크롤러가 실행되는 동안 문자열의 간단한 목록보다 이미 방문한 URL을 저장하는 더 좋은 방법이 있습니까?

2) 여러 세션 사용을 위해 디스크에 영구적으로 데이터를 저장하기 시작했다면이 경우 방문 된 URL을 어떻게 저장 하시겠습니까?

+1

데이터베이스 사용에 좋은 도구 같아서 ​​여기에서 사용하십시오 – Matthew

답변

3

크롤러가 얼마나 빨리 크롤링하는지에 달려 있습니다. 단일 스레드 크롤러를 사용하면 초당 한 페이지보다 평균적으로 훨씬 잘 수행하지 못할 것입니다. 따라서 방문한 URL을 저장하려면 HashSet을 사용할 수 있습니다. 또는 방문한 URL에 대한 정보를 저장하려면 Dictionary<string, UrlInfo>을 사용할 수 있습니다. 여기서 UrlInfo은 방문한 각 URL에 대해 보관하려는 정보가 포함 된 클래스입니다.

하루에 86,400 초일 때 HashSet 또는 Dictionary은 며칠간의 데이터를 저장합니다.

하지만 동일한 사진을 두 번 이상 다운로드하고 싶지는 않을 것입니다. 따라서 내가 "오프라인"또는 "크롤링 프로세스 크롤링"모델이라고 부르는 것이 더 나을 것입니다. 여기 그것이 작동하는 방법입니다.

크롤링을 시작하면 사용자가 식별 한 수천 페이지를 방문합니다. 페이지를 다운로드하고 링크를 추출하고 해당 링크를 로그 파일에 기록합니다. 이미지를 찾으면 이미지를 다운로드하여 저장합니다. 방문하는 모든 페이지도 파일에 기록됩니다.

해당 페이지를 방문했으면 크롤러를 중지합니다. 이제 파일에 저장된 두 개의 목록, 즉 방문한 페이지와 찾은 링크가 있습니다.

방문한 링크를 정렬하고 이전에 방문한 페이지 목록과 병합하십시오. 그 파일은 시간이 지남에 따라 다소 커질 수 있습니다.

추출한 링크 목록을 정렬하고 중복 된 항목을 제거하십시오. 그런 다음 이미 방문한 페이지 목록에 대해 해당 링크를 확인하십시오. 병합이 가장 쉽습니다. 링크를 이미 방문한 경우 삭제하십시오. 그렇지 않으면 다음 크롤링 세션에서 사용할 파일에 저장하십시오.

간단한 데이터베이스에서는이 방법이 더 쉽지만 데이터베이스가 매우 커질 수 있습니다. 데이터베이스를 사용하면 크롤링 프로세스 크롤링 할 필요가 없습니다. 대신, 추출한 각 링크를 데이터베이스와 비교하여 즉시 저장하거나 버릴 수 있습니다.

데이터베이스를 꽤 세게 때려 눕힐 것입니다. 크롤링에 대한 경험이 평균적으로 웹 페이지에는 100 개 이상의 링크가 포함되어 있습니다 (즉, <a href="...">). 이미지는 포함되지 않습니다.단일 스레드 크롤러를 사용하여 초 당 최소 100 번 이상 데이터베이스에 도달하게됩니다.

또 다른 문제는 발견 한 모든 URL을 방문 할 수 없다는 것입니다. 시간이 지남에 평균 웹 페이지에서 추출한 100 개의 링크 중 10 개는 이전에 보지 못한 새로운 링크입니다. 따라서 읽은 모든 페이지에 대해 읽지 않은 페이지가 10 개 더 있습니다. 결국 이미지로 연결될 가능성이없는 URL을 필터링하는 방법이 필요합니다.

내가 방문한 URL을 추적 할 수있는 또 다른 방법은 Bloom Filter입니다. 내 웹 크롤러에서 큰 효과를 발휘하는 데 사용했습니다.

+0

입력 해 주셔서 감사합니다. 차이가 발생하면 내 크롤러가 다중 스레드됩니다. 또한 사전의 문자열 부분에 무엇이 들어갈 수 있습니까? –

+0

@DavidDeMar : URL은 사전의 '문자열'(키)으로 이동합니다. 크롤러가 멀티 스레드 된 경우 동시 업데이트로 인해 크롤러가 손상되지 않도록 사전 (예 : 잠금)에서 동기화가 필요합니다. 또한 위의 추정치에 스레드 수를 곱해야합니다. 데이터베이스가 더 나은 접근 방법처럼 보입니다. –

관련 문제