오늘날 웹 크롤링은 잘 알려진 기술이지만 여전히 많은 복잡성이 있습니다. 간단한 웹 크롤러는 여전히 Ajax Training, XMLHTTPREQUEST, WebSockets, Flash Socket 등과 같은 다양한 복잡한 기술로 개발 된 최신 웹 사이트와 경쟁하기가 여전히 어렵습니다.
HubDoc 프로젝트의 기본 요구 사항을 예로 들어 보겠습니다. 예를 들어, 법안 금액, 만료 날짜, 계좌 번호 및 가장 중요한 것은 은행, 유틸리티 및 신용 카드 회사의 최근 청구서의 PDFS를 기어 올리 봅시다. 이 프로젝트를 위해 저는 매우 간단한 솔루션 (당분간 평가중인 값 비싼 상용 제품을 사용하지 않음)으로 시작했습니다. 그러나 결과는 잘 진행되지 않았으며 스패머는 은행과 유틸리티보다 훨씬 간단한 웹 사이트를 만들었습니다.
그렇다면이 문제를 해결하는 방법은 무엇입니까? 우리는 주로 Mikea를 사용하여 개발 된 우수한 요청 라이브러리부터 시작합니다. 브라우저에서 요청을 한 다음 네트워크 창에서 전송 된 요청 헤더를 확인한 다음 해당 요청 헤더를 코드에 복사하십시오. 이 과정은 매우 간단합니다. 로그인에서 PDF 파일 다운로드까지 모든 요청을 추적 한 다음이 프로세스의 모든 요청을 시뮬레이션하는 것입니다. 비슷한 것을 쉽게 처리하고 Crawler 프로그램을 작성하는 데있어 웹 개발자를보다 합리적으로 만들기 위해 HTML에서 jQuery (Lightweight Cheatio Library 사용)로 결과를 내보내었고, 이는 비슷한 작업을 간단하게 만들었고 CSS 선택기를 사용하여 페이지에서 요소를 선택하는 것이 더 쉬워졌습니다. 전체 프로세스는 프레임 워크로 싸여 있으며 데이터베이스에서 인증서를 선택하고 개별 로봇 로봇을로드하고 Socket.io를 통해 UI와의 통신과 같은 추가 작업을 수행 할 수 있습니다.
이것은 일부 웹 사이트에서 작동하지만이 회사가 사이트에 배치하는 Node.js 코드가 아니라 JS 스크립트 일뿐입니다. 그들은 남은 문제를 계층화하여 복잡성을 해결할 수 있으므로 로그인 정보 지점을 얻기 위해 무엇을 해야하는지 알아 내기가 매우 어렵습니다. 일부 사이트의 경우 며칠 동안 request () 라이브러리와 결합하여 가져 오려고했지만 여전히 헛된 것입니다.
거의 충돌 후, 나는 Node-Phantomjs를 발견했습니다. Node-Phantomjs는 Node에서 Phantomjs 헤드리스 Webkit 브라우저를 제어 할 수있는 라이브러리를 발견했습니다 (번역기 참고 : 해당 명사를 기대하지 않았습니다. 헤드리스는 렌더링 페이지가 장치를 표시하지 않고 백그라운드에서 완료되었음을 의미합니다). 이것은 간단한 솔루션처럼 보이지만 Phantomjs는 피할 수없는 몇 가지 문제가 있습니다.
1. Phantomjs는 페이지가로드되었는지 여부 만 알 수 있지만이 프로세스에서 JavaScript 또는 Meta 태그를 통해 리디렉션 (리디렉션)이 있는지 확인할 수 없습니다. 특히 JavaScript가 settimeout ()을 사용하여 통화를 지연시킬 때.
2. Phantomjs는 위에서 언급 한 문제를 처리 할 수있는 pageloadstarted 후크를 제공하지만이 기능은로드 할 페이지 수를 결정할 때만이 숫자를 줄이고 각 페이지가로드 될 때이 숫자를 줄이고 가능한 시간 초과에 대한 처리를 제공하므로 숫자가 0으로 줄어드는 경우 콜백 기능을 호출 할 수 있습니다. 이 방법은 작동 할 수 있지만 항상 사람들이 해커처럼 느끼게 만듭니다.
3. Phantomjs는 각 페이지에 대해 완전히 독립적이고 독립적 인 프로세스가 필요합니다. 그렇지 않은 경우 각 페이지간에 쿠키를 분리하는 것은 불가능하기 때문입니다. 동일한 phantomjs 프로세스를 사용하는 경우 로그인 된 페이지의 세션이 다른 페이지로 전송됩니다.
4. Phantomjs를 사용하여 리소스를 다운로드 할 수 없습니다. 페이지를 PNG 또는 PDF로만 저장할 수 있습니다. 이것은 유용하지만 PDF를 다운로드하려면 request ()에 의지해야한다는 것을 의미합니다.
5. 위의 이유로 인해 쿠키를 Phantomjs 세션에서 request () 세션 라이브러리로 배포하는 방법을 찾아야합니다. 문서를 배포하고 cookie 문자열을 구문 분석하고 요청한 쿠키 항아리에 주입하십시오 ().
6. 브라우저 세션에 변수를 주입하는 것은 쉽지 않습니다. 이렇게하려면 JavaScript 함수를 만들려면 문자열을 만들어야합니다.
코드 사본은 다음과 같습니다.
robot.prototype.add_page_data = 함수 (페이지, 이름, 데이터) {
page.evaluate (
"function () {var" + name + "= 창." + 이름 + "=" + json.stringify (data) + "}"
);
}
7. 일부 웹 사이트는 항상 Console.log ()와 같은 코드로 채워져 있으며 원하는 위치로 재정의하고 출력해야합니다. 이것을 달성하기 위해 나는 이것을했다 :
코드 사본은 다음과 같습니다.
if (! console.log) {
var iframe = document.createElement ( "iframe");
document.body.appendchild (iframe);
콘솔 = window.frames [0] .console;
}
8. 일부 웹 사이트에는 항상 Console.log ()와 같은 코드로 채워져 있으며 원하는 위치로 재정의하고 출력해야합니다. 이것을 달성하기 위해 나는 이것을했다 :
코드 사본은 다음과 같습니다.
if (! console.log) {
var iframe = document.createElement ( "iframe");
document.body.appendchild (iframe);
콘솔 = window.frames [0] .console;
}
9. A 태그를 클릭 한 브라우저에 브라우저를 알리는 것은 쉽지 않습니다. 이러한 것들을 달성하기 위해 다음 코드를 추가했습니다.
코드 사본은 다음과 같습니다.
var 클릭 = Window.ClickElement = function (id) {
var a = document.getElementById (id);
var e = document.creeevent ( "Mouseevents");
e.initmouseevent ( "클릭", true, true, window, 0, 0, 0, 0, false, false, false, false, 0, null);
a.dispatchevent (e);
};
10. 또한 서버를 폭발시키지 않도록 브라우저 세션의 최대 동시성을 제한해야합니다. 그럼에도 불구하고,이 제한은 비싼 상업용 솔루션이 제공 할 수있는 것보다 훨씬 높습니다. (번역가의 메모 : 즉, 상업용 솔루션의 동시성은이 솔루션의 동시성보다 큽니다)
모든 작업 후에, 나는 Phantomjs + 요청을위한 비교적 괜찮은 크롤러 솔루션을 가지고 있습니다. 요청 () 요청으로 돌아 가기 전에 phantomjs로 로그인해야합니다. Phantomjs로 설정된 쿠키를 사용하여 로그인 세션을 확인합니다. 요청 () 스트림을 사용하여 PDF 파일을 다운로드 할 수 있기 때문에 이것은 큰 승리입니다.
전체 계획은 웹 개발자가 JQuery 및 CSS Selector를 사용하여 다른 웹 사이트의 크롤러를 만드는 방법을 비교적 쉽게 이해할 수 있도록하는 것입니다. 나는이 아이디어가 실현 가능하다는 것을 성공적으로 증명하지 않았지만 곧 일어날 것이라고 믿는다.