Puppeteer 크롤러
이 예제는 PuppeteerCrawler
와
RequestQueue
를 함께 사용하여
헤드리스 Chrome/Puppeteer로 해커 뉴스 웹사이트를 재귀적으로 스크래핑하는 방법을 보여줍니다.
크롤러는 단일 URL에서 시작하여 다음 페이지의 링크를 찾고, 이를 대기열에 추가한 다음 원하는 링크가 더 이상 없을 때까지 계속 진행합니다.
결과는 기본 데이터셋에 저장됩니다. 로컬 환경에서는 결과가 ./storage/datasets/default
경로에 JSON 파일로 저장됩니다.
팁
Apify 플랫폼에서 이 예제를 실행하려면 Dockerfile에서 apify/actor-node-puppeteer-chrome
이미지를 선택하세요.
Run on
import { PuppeteerCrawler } from 'crawlee';
// PuppeteerCrawler 클래스의 인스턴스를 생성합니다.
// 헤드리스 Chrome/Puppeteer에서 URL을 자동으로 로드합니다.
const crawler = new PuppeteerCrawler({
// launchPuppeteer() 함수에 전달되는 옵션을 설정할 수 있습니다.
launchContext: {
launchOptions: {
headless: true,
// 기타 Puppeteer 옵션
},
},
// 크롤링할 페이지 수 제한
maxRequestsPerCrawl: 50,
// 각 URL을 크롤링할 때마다 이 함수가 호출됩니다.
// Crawlee가 브라우저와 페이지를 자동으로 관리하는 것을 제외하면
// 일반적인 Puppeteer 스크립트를 작성하는 것과 동일합니다.
// 이 함수는 다음 필드를 포함하는 객체를 매개변수로 받습니다:
// - request: URL 및 HTTP 메서드와 같은 정보가 포함된 Request 클래스의 인스턴스
// - page: Puppeteer의 Page 객체 (참조: https://pptr.dev/#show=api-class-page)
async requestHandler({ pushData, request, page, enqueueLinks, log }) {
log.info(`${request.url} 처리 중...`);
// 브라우저 컨텍스트 내에서 Puppeteer가 실행할 함수입니다.
const data = await page.$$eval('.athing', ($posts) => {
const scrapedData: { title: string; rank: string; href: string }[] = [];
// Hacker News의 각 게시물에서 제목, 순위, URL을 가져옵니다.
$posts.forEach(($post) => {
scrapedData.push({
title: $post.querySelector('.title a').innerText,
rank: $post.querySelector('.rank').innerText,
href: $post.querySelector('.title a').href,
});
});
return scrapedData;
});
// 결과를 기본 데이터셋에 저장합니다.
await pushData(data);
// 다음 페이지 링크를 찾아 존재하는 경우 큐에 추가합니다.
const infos = await enqueueLinks({
selector: '.morelink',
});
if (infos.processedRequests.length === 0) log.info(`${request.url}가 마지막 페이지입니다!`);
},
// 페이지 처리가 maxRequestRetries+1회 이상 실패하면 이 함수가 호출됩니다.
failedRequestHandler({ request, log }) {
log.error(`${request.url} 요청이 너무 많이 실패했습니다.`);
},
});
await crawler.addRequests(['https://news.ycombinator.com/']);
// 크롤러를 실행하고 완료될 때까지 대기합니다.
await crawler.run();
console.log('크롤러가 완료되었습니다.');