Node.js 웹 스크래핑 도구를 선택할 때는 여러 옵션이 있습니다. 가장 흔히 사용되는 두 가지는 Cheerio와 Puppeteer입니다.
Cheerio는 HTML 문서 파싱 및 조작을 위해 jQuery의 고성능 버전으로 처음 개발되었습니다. 반면 Puppeteer는 웹 페이지 및 애플리케이션 테스트 자동화를 목적으로 만들어졌습니다.
어느 쪽이든 두 도구 모두 웹 스크래핑에 유용합니다: Cheerio는 웹 페이지의 HTML을 파싱하여 필요한 정보를 찾을 수 있게 해주며, Puppeteer는 웹 브라우저를 자동화하여 JavaScript를 사용하는 동적 사이트를 스크래핑할 수 있게 해줍니다.
이 글에서는 두 도구의 기능, 성능, 사용 편의성을 비교해 보겠습니다.
Cheerio 대 Puppeteer
Cheerio와 Puppeteer의 주요 차이점은 Cheerio가 HTML 파서인 반면 Puppeteer는 브라우저 자동화 도구라는 점입니다. 이는 두 도구가 매우 다르게 작동함을 의미합니다.
Cheerio를 사용하면 HTML 문서를 가져와 CSS 선택자를 통해 원하는 HTML 요소를 찾을 수 있습니다.
예를 들어, 다음 선택자를 살펴보세요. h1 태그를 가진 요소를 검색합니다:
const title = $('h1');
이 선택기는 다음과 같은 HTML 코드(example.com에서 가져옴)에 실행할 수 있습니다:
<div>
<h1>Example Domain</h1>
<p>이 도메인은 문서 내 설명용 예시에 사용됩니다. 사전 협의나 허가 없이 문헌에서 이 도메인을 사용할 수 있습니다.</p>
<p><a href="https://www.iana.org/domains/example">추가 정보...</a></p>
</div>
이를 통해 Cheerio는 h1 요소를 반환하며, 여기서 제목 이름과 같은 정보를 추출할 수 있습니다:
<h1>예시 도메인</h1>
Cheerio를 사용하려면 axios와 같은 라이브러리를 활용하여 웹 페이지의 HTML 코드를 가져와야 합니다. 이후 HTML 코드를 파싱하여 필요한 정보를 찾을 수 있습니다.
예를 들어, 다음 코드 샘플은 example.com의 HTML 코드를 다운로드하고 파싱한 후 h1 요소의 텍스트를 찾습니다:
(async () => {
const url = 'https://example.com/';
const response = await axios.get(url); // HTML 가져오기
const $ = cheerio.load(response.data); // Cheerio로 HTML 파싱
const title = $('h1'); // 필요한 데이터 찾기 위해 선택자 사용
console.log(title.text());
})();
반면, Puppeteer는 전용 브라우저 인스턴스를 열고 해당 인스턴스가 제공하는 기능으로 작업합니다. 이는 페이지 HTML에 존재하지 않는 JavaScript 요소와도 상호작용할 수 있음을 의미합니다. 예를 들어, 탐색을 위한 버튼 클릭, 페이지 스크롤, 심지어 페이지 컨텍스트 내에서 JavaScript 실행도 가능합니다.
다음은 브라우저를 실행하고 페이지를 열어 모든 h1 요소의 제목을 추출하는 스크립트 예시입니다. Cheerio와 비교할 때, Puppeteer는 ‘추가 정보’ 버튼과 같은 클릭 가능한 요소를 찾아 탐색에 활용할 수도 있습니다:
(async () => {
const browser = await puppeteer.launch({
headless: false,
defaultViewport: null
});
const page = await browser.newPage(); // 브라우저 열기
await page.goto('https://example.com/'); // 페이지 이동
const title = await page.evaluate(async () => { // 필요한 데이터를 찾기 위해 선택자 사용
const h1 = document.querySelector('h1');
return h1.textContent;
});
console.log(title);
more_information = await page.waitForSelector('a'); // 요소 클릭도 가능!
await more_information.click();
await new Promise(r => setTimeout(r, 2000));
await browser.close(); // 브라우저 닫기
})();
작동 방식의 차이로 인해, Puppeteer는 자바스크립트를 사용하여 웹사이트를 애플리케이션처럼 상호작용하게 만드는 현대적인 웹사이트 스크래핑에 더 적합합니다. 반면 Cheerio는 블로그와 같은 정적 웹사이트에 더 적합합니다.
기능
필요한 정보가 모두 포함된 페이지가 열리면 두 라이브러리 모두 유사하게 작동합니다. CSS 선택자를 사용하여 필요한 정보를 찾아 추출합니다.
Cheerio는 내장된 jQuery와 유사한 구문으로 정보를 찾습니다. 이는 대부분의 자바스크립트 개발자에게 편리합니다:
const title = $('h1');
Puppeteer는 일반적으로 페이지에서 자바스크립트(특히 querySelector 및 querySelectorAll 메서드)를 평가하여 결과를 반환하는 방식으로 정보를 찾습니다:
const title = await page.evaluate(async () => {
const h1 = document.querySelector('h1');
return h1.textContent;
});
그러나 Puppeteer는 브라우저에서 실행되므로 추가 기능을 제공합니다. 예를 들어, 페이지에서 Puppeteer는 사용자가 할 수 있는 모든 작업을 수행할 수 있습니다:
await button.click(); 클릭
await form.type('User'); 입력
이를 통해 등록 및 인증과 같은 모든 종류의 사용자 흐름을 통과할 수 있습니다. 또한 웹사이트 UI를 사용하여 정보를 검색하고, 다른 방법으로는 숨겨진 정보를 찾을 수도 있습니다.
예를 들어 로그인이 필요한 웹사이트가 있다면, Puppeteer로 이를 수행하는 것은 매우 간단합니다—필요한 필드를 클릭하고 사용자 이름과 비밀번호를 입력하기만 하면 됩니다. 나머지는 브라우저가 처리합니다. 반면 Cheerio는 단일 페이지 파싱만 담당하고 웹 세션을 관리하지 않기 때문에, 기술적으로 계정에 로그인할 수 없습니다.
Puppeteer는 페이지 내용을 조작하기 위해 임의의 자바스크립트도 실행할 수 있습니다. 이는 주로 페이지 스크롤에 활용됩니다. 따라서 Puppeteer를 사용하면 무한 스크롤 웹사이트를 스크래핑할 수 있지만, Cheerio는 첫 페이지 외에는 아무것도 로드하지 못합니다. 또한 맞춤형 스크래핑 방지 조치를 우회하기에도 더 용이합니다.
스크래핑이 브라우저 내에서 자연스러운 동작으로 수행된다는 점은 디버깅에도 매우 유용합니다! 헤드리스 모드를 비활성화하면 실행 과정을 관찰하며 웹사이트의 문제를 즉시 파악할 수 있습니다:

성능
Puppeteer는 웹 스크래핑을 구현하기 위해 브라우저를 시작하고 실행해야 하므로, 스크립트 시작 및 실행 속도가 Cheerio보다 현저히 느리며 더 많은 컴퓨팅 자원을 소모합니다.
예를 들어, 다음은 기본 웹 페이지 스크래핑에 소요되는 라이브러리 속도를 간단히 비교한 결과입니다.
다음 스크립트를 사용하면 Bright Data 블로그를 열고 첫 페이지에서 블로그 게시물 링크를 추출할 수 있습니다:
Cheerio
async function cheerio_scrape() {
const url = 'https://brightdata.com/blog';
const response = await axios.get(url);
const $ = cheerio.load(response.data);
const h5s = $('h5');
let titles = []
h5s.each((i, el) => titles.push($(el).text().trim()));
console.log(titles);
};
Puppeteer
async function puppeteer_scrape() {
const browser = await puppeteer.launch({
headless: false,
defaultViewport: null
});
const page = await browser.newPage();
await page.goto('https://brightdata.com/blog');
await page.waitForSelector('h5');
const titles = await page.evaluate(async () => {
let titles = [];
const h5s = document.querySelectorAll('h5');
h5s.forEach(el => titles.push(el.textContent.trim()));
return titles;
});
console.log(titles);
await browser.close();
};
그런 다음 두 함수의 실행 시간을 측정할 수 있습니다.
다음 코드는 Cheerio 스크립트의 실행 시간을 측정합니다. 약 500밀리초가 소요됩니다(환경에 따라 다를 수 있음):
let start = Date.now();
cheerio_scrape().then(() => {
let end = Date.now();
console.log(`실행 시간: ${end - start} ms`);
});
다음 코드는 Puppeteer 스크립트의 실행 시간을 측정합니다:
let start = Date.now();
puppeteer_scrape().then(() => {
let end = Date.now();
console.log(`실행 시간: ${end - start} ms`);
});
Puppeteer를 사용하면 스크립트 완료까지 약 4,000밀리초가 소요되며, 이는 Cheerio가 소요하는 500밀리초보다 훨씬 긴 시간입니다.
사용 편의성
웹 스크래핑을 처음 접하는 경우, Cheerio가 더 적합할 수 있습니다. Cheerio는 페이지의 HTML 코드만 다루기 때문입니다. 사용자는 웹 요소와 상호작용하거나 로딩 시간에 맞춰 스크립트를 조정할 필요가 없어, 올바른 선택자 생성 같은 중요한 웹 스크래핑 본질에 집중할 수 있습니다.
또한 Cheerio를 사용하면 웹 페이지의 HTML 코드는 다운로드 후 변경되지 않습니다. 반면 자바스크립트를 실행하고 상호작용이 발생하는 웹사이트의 경우 HTML이 지속적으로 변경되며, 변경 시점이 다소 예측하기 어렵습니다.
이러한 이유로 브라우저 자동화 도구들은 대기(wait) 기능을 사용합니다. 특히 Puppeteer는 페이지에 요소가 존재하는지 같은 조건이 충족될 때까지 기다리는 waitForSelector 함수를 제공합니다. 지정된 시간(기본값 30초)이 지나도 요소가 존재하지 않으면 스크립트는 다음과 같은 오류를 발생시킵니다:
await page.waitForSelector('h1')
제대로 설정하지 않으면 지연으로 인해 스크립트의 신뢰성이 크게 떨어질 수 있습니다.
또한 Cheerio의 구문은 자바스크립트 개발자에게 더 간단하고 자연스럽게 느껴질 것입니다. Puppeteer는 강력하지만 웹 스크래핑을 염두에 두고 만들어진 것은 아니며, 이를 사용해 보면 그 한계가 드러납니다.
결론
이 글에서는 자바스크립트 생태계에서 흔히 사용되는 두 가지 웹 스크래핑 라이브러리인 Cheerio와 Puppeteer를 살펴보았습니다. 작동 방식의 차이로 인해 각각 장단점이 있습니다. Cheerio는 정적 페이지를 대상으로 하는 간단한 웹 스크래핑 스크립트에 훨씬 적합한 반면, Puppeteer는 현대적인 자바스크립트 기반 웹 페이지에서 정보를 추출하는 데 유용합니다.
중요한 점은 이 두 도구 모두 웹 스크래핑을 위해 특별히 고안된 것은 아니라는 것입니다. HTML 작업 및 브라우저 자동화 기능을 제공하기 때문에 웹사이트를 스크래핑하려는 개발자들이 이 도구들을 활용해 왔습니다. 이는 이 도구들이 제공하는 인터페이스가 웹 스크래퍼의 요구와 필요에 맞춰져 있지 않음을 의미합니다.
강력하면서도 사용하기 쉬운 솔루션을 찾고 있다면, 포괄적인 웹 스크래핑 서비스인 Bright Data를 살펴보시기 바랍니다. Bright Data는 웹사이트 스크래핑 및 브라우저 자동화 도구 외에도, 포춘 500대 기업 수십 곳과 20,000명 이상의 고객을 지원하는 최대 규모의 프록시 서비스 제공업체입니다. 전 세계적인 프록시 네트워크는 다음과 같습니다:
- 데이터센터 프록시
- 주거용 프록시
- ISP 프록시
지금 무료 체험을 시작하세요.