JSDOM 크롤러
이 예제는 jsdom DOM 구현을 사용하여 웹사이트와 상호 작용하는 JSDOMCrawler
의 사용법을 보여줍니다.
이 스크립트는 React 예제의 계산기 앱을 열고, 1
+
1
=
를 클릭한 다음 결과값을 추출합니다.
Run on
import { JSDOMCrawler, log } from 'crawlee';
// JSDOMCrawler 클래스의 인스턴스를 생성합니다 - jsdom 라이브러리를 사용하여
// URL을 자동으로 로드하고 HTML을 파싱하는 크롤러입니다.
const crawler = new JSDOMCrawler({
// `runScripts` 옵션을 `true`로 설정하면 크롤러가 페이지에서 클라이언트 측
// JavaScript 코드를 실행할 수 있습니다. 이는 일부 웹사이트(이 예제의 React 애플리케이션과 같은)에
// 필요하지만 보안 위험이 있을 수 있습니다.
runScripts: true,
// 이 함수는 크롤링된 각 URL에 대해 호출됩니다.
// 여기서는 옵션에서 window 객체를 추출하여 페이지에서 데이터를 추출하는 데 사용합니다.
requestHandler: async ({ window }) => {
const { document } = window;
// `document` 객체는 웹 브라우저에서 사용하는 `window.document` 객체와 동일합니다.
// 따라서 일반적인 브라우저 API를 여기서 사용할 수 있습니다.
document.querySelectorAll('button')[12].click(); // 1
document.querySelectorAll('button')[15].click(); // +
document.querySelectorAll('button')[12].click(); // 1
document.querySelectorAll('button')[18].click(); // =
const result = document.querySelectorAll('.component-display')[0].childNodes[0] as Element;
// 결과는 콘솔에 출력됩니다. Playwright나 Puppeteer 크롤러와 달리,
// 이 콘솔 출력은 브라우저 콘솔이 아닌 Node.js 콘솔로 전달됩니다. 여기의 모든 코드는 Node.js에서 직접 실행됩니다!
log.info(result.innerHTML); // 2
},
});
// 크롤러를 실행하고 완료될 때까지 대기합니다.
await crawler.run(['https://ahfarmer.github.io/calculator/']);
log.debug('크롤러가 완료되었습니다.');
다음 예제에서는 JSDOMCrawler
를 사용하여 외부 파일에서 URL 목록을 크롤링하고, 일반 HTTP 요청을 통해 각 URL을 로드한 다음 jsdom DOM 구현을 사용하여 HTML을 파싱하고 페이지 제목과 모든 h1
태그와 같은 데이터를 추출합니다.
Run on
import { JSDOMCrawler, log, LogLevel } from 'crawlee';
// 크롤러에는 로깅과 같은 다양한 유틸리티가 포함되어 있습니다.
// 디버깅 경험을 향상시키기 위해 여기서는 디버그 수준의 로깅을 사용합니다.
// 이 기능은 선택사항입니다!
log.setLevel(LogLevel.DEBUG);
// JSDOMCrawler 클래스의 인스턴스를 생성합니다.
// URL을 자동으로 로드하고 jsdom 라이브러리를 사용하여 HTML을 파싱하는 크롤러입니다.
const crawler = new JSDOMCrawler({
// 크롤러는 웹 페이지를 병렬로 다운로드하고 처리합니다.
// 동시성은 사용 가능한 시스템 메모리와 CPU를 기반으로 자동 관리됩니다(AutoscaledPool 클래스 참조).
// 여기서는 동시성에 대한 제한을 설정합니다.
minConcurrency: 10,
maxConcurrency: 50,
// 오류 발생 시 각 페이지를 최대 한 번만 재시도합니다.
maxRequestRetries: 1,
// 각 페이지 처리 시간 제한을 늘립니다.
requestHandlerTimeoutSecs: 30,
// 크롤링당 최대 10개의 요청으로 제한합니다.
maxRequestsPerCrawl: 10,
// 이 함수는 크롤링할 각 URL에 대해 호출됩니다.
// 옵션이 포함된 객체를 매개변수로 받습니다:
// https://crawlee.dev/api/jsdom-crawler/interface/JSDOMCrawlerOptions#requestHandler
// 데모를 위해 다음 2가지만 사용합니다:
// - request: 크롤링 중인 URL 및 HTTP 메서드와 같은 정보가 포함된 Request 클래스의 인스턴스
// - window: JSDOM window 객체
async requestHandler({ pushData, request, window }) {
log.debug(`Processing ${request.url}...`);
// 페이지에서 데이터 추출
const title = window.document.title;
const h1texts: { text: string }[] = [];
window.document.querySelectorAll('h1').forEach((element) => {
h1texts.push({
text: element.textContent!,
});
});
// 결과를 데이터셋에 저장합니다. 로컬 구성에서는
// 데이터가 ./storage/datasets/default에 JSON 파일로 저장됩니다
await pushData({
url: request.url,
title,
h1texts,
});
},
// 이 함수는 페이지 처리가 maxRequestRetries + 1회 이상 실패한 경우 호출됩니다.
failedRequestHandler({ request }) {
log.debug(`Request ${request.url} failed twice.`);
},
});
// 크롤러를 실행하고 완료될 때까지 대기합니다.
await crawler.run(['https://crawlee.dev']);
log.debug('Crawler finished.');