Node.js와 Puppeteer: 웹 자동화와 스크래핑의 강력한 조합

Node.js

Puppeteer는 Google Chrome 팀에서 개발한 Node.js 라이브러리로, 헤드리스 Chrome 또는 Chromium을 제어하여 웹 자동화, 테스팅, 스크래핑 등 다양한 작업을 수행할 수 있게 해줍니다. 이 강력한 도구를 통해 개발자들은 브라우저에서 할 수 있는 거의 모든 작업을 자동화할 수 있습니다.

Puppeteer란?

Puppeteer는 고수준 API를 통해 Chrome DevTools Protocol을 사용하여 Chrome 또는 Chromium을 제어합니다. 기본적으로 헤드리스 모드(GUI 없이)로 실행되지만, 필요에 따라 전체 브라우저 인터페이스를 표시할 수도 있습니다.

주요 기능

  • 웹 스크래핑: 동적 콘텐츠를 포함한 웹사이트의 데이터 추출
  • 자동화된 테스팅: UI 테스트, 폼 제출, 키보드 입력 등 자동화
  • PDF 생성: 웹페이지의 PDF 파일 생성
  • 스크린샷 캡처: 전체 페이지 또는 특정 요소의 스크린샷 생성
  • 성능 분석: 웹사이트 성능 측정 및 추적
  • SPA 테스팅: 단일 페이지 애플리케이션(SPA)의 테스팅

시작하기

Node.js 프로젝트에 Puppeteer를 설치하는 것은 간단합니다:

npm install puppeteer

간단한 예제로 시작해보겠습니다:

const puppeteer = require('puppeteer');

async function example() {
  // 브라우저 실행
  const browser = await puppeteer.launch();
  
  // 새 페이지 열기
  const page = await browser.newPage();
  
  // 페이지로 이동
  await page.goto('https://example.com');
  
  // 페이지 제목 가져오기
  const title = await page.title();
  console.log('페이지 제목:', title);
  
  // 스크린샷 찍기
  await page.screenshot({ path: 'example.png' });
  
  // PDF 생성
  await page.pdf({ path: 'example.pdf', format: 'A4' });
  
  // 브라우저 닫기
  await browser.close();
}

example();

웹 스크래핑 예제

웹사이트에서 데이터를 추출하는 간단한 예제입니다:

const puppeteer = require('puppeteer');

async function scrapeData() {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  
  await page.goto('https://news.ycombinator.com');
  
  // 페이지에서 데이터 추출
  const headlines = await page.evaluate(() => {
    const titles = Array.from(document.querySelectorAll('.titleline > a'));
    return titles.map(title => ({
      text: title.innerText,
      href: title.href
    }));
  });
  
  console.log('추출된 헤드라인:', headlines);
  
  await browser.close();
}

scrapeData();

폼 자동화 예제

로그인 폼을 자동으로 채우고 제출하는 예제입니다:

const puppeteer = require('puppeteer');

async function autoFillForm() {
  const browser = await puppeteer.launch({ headless: false }); // GUI로 확인
  const page = await browser.newPage();
  
  await page.goto('https://example.com/login');
  
  // 폼 필드 채우기
  await page.type('#username', 'your_username');
  await page.type('#password', 'your_password');
  
  // 폼 제출 및 페이지 이동 대기
  await Promise.all([
    page.click('#login-button'),
    page.waitForNavigation()
  ]);
  
  console.log('로그인 성공!');
  
  await browser.close();
}

autoFillForm();

고급 기능

브라우저 콘텍스트 조작

// 쿠키 설정
await page.setCookie({ name: 'token', value: 'your-auth-token', domain: 'example.com' });

// 로컬 스토리지 조작
await page.evaluate(() => {
  localStorage.setItem('user', JSON.stringify({ id: 1, name: 'John' }));
});

// 사용자 에이전트 설정
await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X)');

성능 모니터링

// 성능 트레이스 시작
await page.tracing.start({ path: 'trace.json' });

await page.goto('https://example.com');

// 트레이스 종료
await page.tracing.stop();

실전 팁

리소스 제한: 불필요한 리소스 요청을 차단하여 속도 향상

await page.setRequestInterception(true);
page.on('request', (req) => {
  if (req.resourceType() === 'image' || req.resourceType() === 'font') {
    req.abort();
  } else {
    req.continue();
  }
});

병렬 처리: 여러 작업을 동시에 처리

const urls = ['url1', 'url2', 'url3'];
const browser = await puppeteer.launch();

const results = await Promise.all(urls.map(async (url) => {
  const page = await browser.newPage();
  await page.goto(url);
  const title = await page.title();
  await page.close();
  return { url, title };
}));

헤드리스 Chrome 디버깅: 문제 해결을 위한 디버깅

const browser = await puppeteer.launch({
  headless: false,
  devtools: true
});

주의사항

  1. 윤리적 스크래핑: 웹사이트의 robots.txt를 존중하고, 서버에 과도한 부하를 주지 않도록 요청 간격 조절
  2. 캡차 및 봇 탐지: 일부 사이트는 자동화된 접근을 방지하기 위한 시스템 보유
  3. 메모리 관리: 장시간 실행 시 메모리 누수 방지를 위해 브라우저와 페이지 리소스 정리

결론

Puppeteer는 웹 자동화와 테스팅에 있어 강력한 도구로, 개발자의 일상적인 작업을 단순화하고 자동화할 수 있습니다. 웹 스크래핑부터 UI 테스팅, 성능 분석까지 다양한 작업에 활용할 수 있으며, 지속적으로 발전하고 있는 생태계를 가지고 있습니다.

이 도구를 효과적으로 활용하면 개발 워크플로우를 크게 개선할 수 있으며, 특히 반복적인 작업이나 대규모 데이터 수집이 필요한 경우 큰 도움이 됩니다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤