문제

Wget 매뉴얼에서 다음 문장이 눈에 들어왔습니다.

wget --spider --force-html -i bookmarks.html

This feature needs much more work for Wget to get close to the functionality of real web spiders.

wget의 스파이더 옵션과 관련된 다음 코드 줄을 찾았습니다.

src/ftp.c
780:      /* If we're in spider mode, don't really retrieve anything.  The
784:      if (opt.spider)
889:  if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
1227:      if (!opt.spider)
1239:      if (!opt.spider)
1268:      else if (!opt.spider)
1827:          if (opt.htmlify && !opt.spider)

src/http.c
64:#include "spider.h"
2405:  /* Skip preliminary HEAD request if we're not in spider mode AND
2407:  if (!opt.spider
2428:      if (opt.spider && !got_head)
2456:      /* Default document type is empty.  However, if spider mode is
2570:           * spider mode.  */
2571:          else if (opt.spider)
2661:              if (opt.spider)

src/res.c
543:  int saved_sp_val = opt.spider;
548:  opt.spider       = false;
551:  opt.spider       = saved_sp_val;  

src/spider.c
1:/* Keep track of visited URLs in spider mode.
37:#include "spider.h"
49:spider_cleanup (void)

src/spider.h
1:/* Declarations for spider.c

src/recur.c
52:#include "spider.h"
279:      if (opt.spider)
366:              || opt.spider /* opt.recursive is implicitely true */
370:             (otherwise unneeded because of --spider or rejected by -R) 
375:                   (opt.spider ? "--spider" : 
378:                     (opt.delete_after || opt.spider
440:      if (opt.spider) 

src/options.h
62:  bool spider;           /* Is Wget in spider mode? */

src/init.c
238:  { "spider",           &opt.spider,            cmd_boolean },

src/main.c
56:#include "spider.h"
238:    { "spider", 0, OPT_BOOLEAN, "spider", -1 },
435:       --spider                  don't download anything.\n"),
1045:  if (opt.recursive && opt.spider)

추상적이 아닌 코드의 차이점을 확인하고 싶습니다.나는 코드 예제를 좋아합니다.

웹 스파이더는 Wget의 스파이더와 어떻게 다른가요? 코드에서?

도움이 되었습니까?

해결책

진짜 거미는 많은 일입니다

WWW 전체를위한 거미를 쓰는 것은 상당히 일입니다 .-- 당신은 다음과 같은 많은 "작은 세부 사항"을 돌봐야합니다.

  • 각 스파이더 컴퓨터는 연결 대역폭을 효율적으로 사용하기 위해 수천 개의 서버에서 데이터를 병렬로 수신해야합니다. (비동기 소켓 I/O).
  • www에 대한 방대한 양의 정보를 다루기 위해 스파이더가있는 여러 컴퓨터가 필요합니다 (클러스터링; 작업 파티셔닝).
  • 거미있는 웹 사이트에 공손해야합니다.
    • robots.txt 파일을 존중하십시오.
    • 많은 정보를 너무 빨리 가져 오지 마십시오. 서버에 과부하가 걸립니다.
    • 실제로 필요하지 않은 파일을 가져 오지 마십시오 (예 : ISO 디스크 이미지; 소프트웨어 다운로드 용 TGZ 패키지 ...).
  • 쿠키/세션 ID를 처리해야합니다. 많은 사이트가 클라이언트 세션을 식별하기 위해 고유 한 세션 ID를 URL에 첨부합니다. 사이트에 도착할 때마다 새로운 세션 ID와 새로운 가상 페이지 (동일한 콘텐츠)가 제공됩니다. 이러한 문제로 인해 초기 검색 엔진은 동적 콘텐츠를 무시했습니다. 현대 검색 엔진은 문제가 무엇인지, 다루는 방법을 배웠습니다.
  • 귀찮은 데이터를 감지하고 무시해야합니다 : 완료하기에는 너무 느리게 겉보기에 무한한 양의 데이터 또는 연결을 제공하는 연결.
  • 다음 링크 외에도 구문 분석 할 수 있습니다 사이트 맵 페이지의 URL을 얻으려면
  • 귀하에게 중요한 정보를 평가하고 다른 페이지보다 자주 새로 고치는 정보를 평가할 수 있습니다. 참고 : WWW 전체를위한 거미는 많은 데이터를받습니다. HTTP 헤드 요청을 사용하여 페이지가 변경되었는지 여부를 추측 할 수 있습니다.
  • 받는 것 외에도 정보를 처리하고 저장하려고합니다. Google은 각 단어에 대해 해당 표시를 포함하는 페이지를 구축합니다. 연결하려면 별도의 스토리지 컴퓨터와 인프라가 필요할 수 있습니다. 전통적인 관계형 데이터베이스는 전체 www를 저장/인덱싱하는 데이터 볼륨 및 성능 요구 사항을 따르지 않습니다.

이것은 많은 일입니다. 그러나 목표가 전체 WWW를 읽는 것보다 타겟이 더 겸손하다면 일부 부품을 건너 뛸 수 있습니다. 위키 등의 사본을 다운로드하려면 wget의 사양으로 내려갑니다.

참고 : 그것이 너무 많은 일이라고 믿지 않는다면, Google이 대부분의 컴퓨팅 휠 (기본 Linux 커널 위에)을 다시 발명하여 좋은 거미를 구축하는 방법에 대해 읽을 수 있습니다. 코너를 많이 자르더라도 많은 일입니다.

세 점에 대해 몇 가지 기술 발언을 추가하겠습니다.

병렬 연결 / 비동기 소켓 통신

병렬 프로세스 또는 스레드로 여러 스파이더 프로그램을 실행할 수 있습니다. 그러나 네트워크 연결을 잘 활용하려면 약 5000-10000 병렬 연결이 필요합니다. 그리고이 양의 병렬 프로세스/스레드는 너무 많은 오버 헤드를 생성합니다.

더 나은 솔루션은 비동기 입력/출력입니다. 비 블로킹 모드에서 소켓을 열어서 한 단일 스레드에서 약 1000 개의 병렬 연결을 처리하고 Epoll을 사용하거나 데이터를 수신 한 연결 만 처리하기 위해 선택하십시오. Linux Kernel 2.4 이후 Linux는 이후 버전에서 지속적으로 개선 된 확장 성 (메모리 매핑 파일을 연구하는 것이 좋습니다)에 대한 탁월한 지원을 제공합니다.

참고 : 비동기 I/O를 사용하면 "빠른 언어"를 사용하는 것보다 훨씬 많은 도움이됩니다. Perl에 작성된 프로세스와 100MB 연결을 포화하십시오.

원래 답변에서 : 이 접근법의 아래쪽은 HTTP 사양을 비동기 형태로 직접 구현해야한다는 것입니다 (이를 수행하는 재사용 가능한 라이브러리를 모릅니다). 최신 HTTP/1.1 프로토콜보다 간단한 HTTP/1.0 프로토콜로이를 수행하는 것이 훨씬 쉽습니다. 어쨌든 일반 브라우저의 HTTP/1.1의 장점으로부터 혜택을받지 못할 것이므로 개발 비용을 절약하기에 좋은 장소 일 수 있습니다.

5 년 후 편집 :오늘날,이 작업에 도움이되는 무료/오픈 소스 기술이 많이 있습니다. 나는 개인적으로 비동기식을 좋아합니다 HTTP 구현node.js --- 위의 원래 단락에서 언급 된 모든 작업을 저장합니다. 물론 오늘날 거미에 필요한 다른 구성 요소에 쉽게 사용할 수있는 많은 모듈이 있습니다. 그러나 타사 모듈의 품질은 상당히 다를 수 있습니다. 사용하는 모든 것을 확인해야합니다. 노화 정보 : 최근에 Node.js를 사용하여 거미를 썼으며 링크 및 데이터 추출에 대한 HTML 처리를위한 NPM 모듈의 신뢰성이 충분하지 않다는 것을 알았습니다. 이 작업의 경우이 처리를 다른 프로그래밍 언어로 작성된 프로세스로 "아웃소싱"했습니다. 그러나 상황이 빠르게 변하고 있으며이 의견을 읽을 때이 문제는 이미 과거의 일일 수 있습니다 ...

여러 서버를 통해 작업을 분할합니다

하나의 컴퓨터는 전체 www를 거미줄을 따라갈 수 없습니다. 여러 서버를 통해 작업을 배포하고 정보간에 정보를 교환해야합니다. 각 서버에 특정 "도메인 이름의 범위"를 할당하는 것이 좋습니다. 스파이더 컴퓨터를 참조하여 도메인 이름의 중앙 데이터베이스를 유지하십시오.

수신 된 웹 페이지에서 URL을 배치로 추출합니다. 도메인 이름에 따라 정렬하십시오. 복제물을 제거하고 책임있는 스파이더 컴퓨터로 보내십시오. 해당 컴퓨터에서 이미 가져온 URL 인덱스를 유지하고 나머지 URL을 가져 오십시오.

각 스파이더 컴퓨터에서 URL 대기열을 유지하면 성능 병목 현상이 없을 것입니다. 그러나 이것을 구현하는 것은 많은 프로그래밍입니다.

표준을 읽으십시오

여러 표준 (http/1.x, robots.txt, 쿠키)을 언급했습니다. 시간을내어 읽고 구현하십시오. 알고있는 사이트의 예제를 따르면 실수를 저지르고 (샘플과 관련이없는 표준의 일부를 잊어 버리고) 이러한 추가 기능을 사용하는 사이트에 문제가 발생합니다.

HTTP/1.1 표준 문서를 읽는 것은 고통입니다. 그러나 누군가가 실제로 그 작은 세부 사항이 필요하고 이제 사용하기 때문에 모든 작은 세부 사항이 추가되었습니다.

다른 팁

나는 댓글의 원래 저자가 무엇을 언급했는지 정확히 잘 모르겠지만, wget은 단일 실행 스레드 (적어도 당신이 보여준 것에 의한 것) 만 사용하는 것처럼 보이기 때문에 wget은 거미처럼 느리다고 생각할 수 있습니다.

"진짜"거미와 같은 헤리트릭스 많은 병렬성과 트릭을 사용하여 크롤링 속도를 최적화하는 반면 동시에 크롤링하는 웹 사이트에 적합합니다. 이는 일반적으로 초당 1의 속도로 한 사이트로 히트를 제한하고 동시에 여러 웹 사이트를 크롤링하는 것을 의미합니다.

다시 이것은 모두 내가 거미에 대해 알고있는 것과 여기에 게시 한 내용을 기반으로 한 추측 일뿐입니다.

불행히도, 더 잘 알려진 '실제'웹 거미는 폐쇄 소스이며 실제로 폐쇄 된 이진입니다. 그러나 WGET가 누락 된 여러 기본 기술이 있습니다.

  • 병행; 한 번에 여러 페이지를 검색하지 않고 전체 웹을 따라갈 수 없을 것입니다.
  • 우선 순위; 일부 페이지는 다른 페이지보다 거미에 더 중요합니다
  • 요율 제한; 가능한 한 빨리 페이지를 계속 끌어 내면 빨리 금지됩니다.
  • 로컬 파일 시스템 이외의 다른 것에 저장; 웹은 단일 디렉토리 트리에 맞지 않을 정도로 큽니다.
  • 전체 프로세스를 다시 시작하지 않고 주기적으로 페이지를 다시 확인합니다. 실제로, 실제 거미를 사용하면 업데이트를 자주 사용할 '중요한'페이지를 다시 확인하고 싶지만 덜 흥미로운 페이지는 몇 달 동안 갈 수 있습니다.

사이트 맵 등과 같이 사용할 수있는 다양한 입력도 있습니다. 포인트, WGET는 전체 웹을 스파이더하도록 설계되지 않았으며, 작은 코드 샘플에서 캡처 할 수있는 것은 아닙니다. 단 하나의 작은 서브 루틴이 잘못 되었기보다는 전체 기술이 사용되는 전체 기술의 문제이기 때문입니다. 작업을 위해.

나는 인터넷을 스파이더링하는 방법에 대해 자세히 설명하지 않을 것입니다. 제 생각에는 wget 댓글이 여전히 심각한 문제인 한 웹사이트를 스파이더링하는 것에 관한 것 같습니다.

  • 스파이더로서 URL이 날짜=1/1/1900에서 1/2/1900으로 변경되었다는 이유로 재귀 크롤링을 시작하지 않고 언제 중지해야 하는지 파악해야 합니다.
  • URL 재작성을 분류하는 것은 훨씬 더 큰 과제입니다(Google이나 다른 곳에서 이를 어떻게 처리하는지 전혀 모르겠습니다).충분히 크롤링하지만 너무 많이 크롤링하는 것은 꽤 큰 도전입니다.그리고 임의의 매개변수와 콘텐츠의 임의 변경으로 인해 URL 재작성을 자동으로 인식할 수 있는 방법은 무엇입니까?
  • 적어도 일정 수준까지는 Flash/Javascript를 구문 분석해야 합니다.
  • 다음과 같은 미친 HTTP 문제를 고려해야 합니다. 베이스 꼬리표.대부분의 웹사이트가 XHTML이 아니고 브라우저의 구문이 매우 유연하다는 점을 고려하면 HTML을 구문 분석하는 것조차 쉽지 않습니다.

wget에서 이들 중 얼마나 많이 구현되거나 고려되었는지는 모르지만 이 작업의 과제를 이해하기 위해 httrack을 살펴보는 것이 좋습니다.

몇 가지 코드 예제를 제공하고 싶지만 이것은 큰 작업이며 괜찮은 스파이더는 약 5000 loc입니다. 타사 라이브러리 없이.

+ 그 중 일부는 이미 @yaakov-belch에 의해 설명되었으므로 다시 입력하지 않겠습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top