NodeJs

[NODE JS] puppeteer를 활용한 Crawing

dbsxo4083 2024. 9. 2. 15:39

크롤링(Crawling)이란 웹페이지를 자동화된 방법으로 방문하고, 해당 페이지의 콘텐츠를 수집하는 과정을 의미합니다. 이 과정은 주로 검색 엔진, 데이터 분석, 웹 스크래핑 등의 목적으로 사용됩니다. 웹 크롤러(또는 스파이더)는 이 작업을 수행하는 프로그램이나 스크립트를 의미하며, 주어진 웹사이트를 체계적으로 탐색하면서 해당 페이지의 HTML, 텍스트, 이미지, 링크 등 다양한 정보를 가져옵니다.

크롤링의 주요 용도

  1. 검색 엔진 인덱싱:
    • 검색 엔진(예: Google, Bing)은 웹 크롤러를 사용해 인터넷 상의 수많은 웹페이지를 방문하고, 그 내용을 분석하여 검색 인덱스를 생성합니다. 이 인덱스를 바탕으로 사용자가 검색어를 입력하면 관련된 웹페이지를 검색 결과로 보여줍니다.
  2. 웹 스크래핑:
    • 특정 웹사이트에서 필요한 데이터를 추출하고, 이를 저장하거나 분석하는 데 사용됩니다. 예를 들어, 뉴스 사이트에서 기사 제목과 본문을 수집하거나, 쇼핑몰에서 상품 정보를 수집할 때 크롤링을 사용합니다.
  3. 데이터 수집 및 분석:
    • 연구 목적이나 시장 분석을 위해 특정 웹사이트에서 데이터를 수집하여 분석하는 데 활용됩니다.
  4. 모니터링 및 알림:
    • 웹사이트의 변화를 모니터링하고, 새로운 콘텐츠가 추가되거나 수정될 때 알림을 받는 데 사용될 수 있습니다.

Puppeteer는 구글에서 개발한 Node.js 라이브러리로, 헤드리스(Headless) 브라우저인 Chromium 또는 Chrome을 제어할 수 있게 해줍니다. Puppeteer를 사용하면 코드로 브라우저를 제어할 수 있으며, 웹페이지의 스크린샷을 찍거나 PDF로 저장하는 것부터, 웹 애플리케이션을 테스트하거나 크롤링, 웹 스크래핑 등 다양한 작업을 자동화할 수 있습니다.

Puppeteer의 주요 기능

  1. 웹 페이지 탐색 및 조작:
    • Puppeteer를 통해 브라우저를 실행하고, 특정 웹페이지로 이동한 후, 그 페이지에서 사용자가 직접 브라우저를 사용하듯이 요소를 클릭하거나 텍스트를 입력하는 등의 작업을 코드로 자동화할 수 있습니다.
  2. 스크린샷 및 PDF 생성:
    • 웹페이지의 현재 상태를 스크린샷으로 캡처하거나, 페이지 전체를 PDF 파일로 저장할 수 있습니다.
  3. 웹 스크래핑:
    • 특정 웹페이지에서 데이터를 추출하는 작업을 자동화할 수 있습니다. Puppeteer는 JavaScript가 실행된 후의 페이지 콘텐츠를 가져올 수 있어, 동적 콘텐츠가 많은 웹사이트의 데이터를 수집하는 데 유리합니다.
  4. 크로스브라우저 테스트:
    • Puppeteer는 자동화된 브라우저 테스트를 지원하며, 이를 통해 웹 애플리케이션이 다양한 브라우저 환경에서 제대로 동작하는지 확인할 수 있습니다.
  5. 자동화된 브라우저 작업:
    • 로그인 자동화, 폼 제출, UI 테스트, 퍼포먼스 측정 등 브라우저에서 수행할 수 있는 다양한 작업을 자동으로 처리할 수 있습니다.
  6. 헤드리스 및 풀 브라우저 모드 지원:
    • 기본적으로는 UI 없이 동작하는 헤드리스 모드로 실행되지만, UI를 포함한 브라우저 창을 띄운 상태로도 실행할 수 있습니다.

 

- puppeteer 설치 

npm install puppeteer

 

Puppeteer의 기본 사용법

Puppeteer의 간단한 사용 예시는 다음과 같습니다:

 
const puppeteer = require('puppeteer');

(async () => {
  // 브라우저 실행
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // 특정 웹페이지로 이동
  await page.goto('https://example.com');

  // 스크린샷 캡처
  await page.screenshot({ path: 'example.png' });

  // 브라우저 닫기
  await browser.close();
})();

Puppeteer의 장점

  • 동적 콘텐츠 처리: JavaScript가 완전히 로드된 상태의 웹페이지 콘텐츠를 다룰 수 있어, AJAX나 SPA(Single Page Application) 같은 동적 웹페이지를 크롤링하거나 스크래핑하는 데 유용합니다.
  • 브라우저 환경과 동일한 조건: 실제 브라우저 환경에서 작업이 이루어지기 때문에, 브라우저에서 발생하는 모든 상황을 시뮬레이션할 수 있습니다.

Puppeteer는 웹 자동화, 스크래핑, 테스트 등에 있어 강력한 기능을 제공하는 도구로, Node.js 환경에서 매우 유용하게 사용할 수 있습니다.

 

Puppeteer를 사용한 Coinness 기사 크롤링

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();

  await page.goto('https://coinness.com', { waitUntil: 'networkidle2' });

  const texts = await page.evaluate(() => {
    const childElements = document.querySelectorAll('.BreakingNewsContents-sc-glfxh-5.bULVI.omit');
    return Array.from(childElements).map(child => child.innerText);
  });

  console.log(texts);

  await browser.close();
})();

 

실행결과

 

코드 리뷰

  • 모듈 불러오기
    • Puppeteer 라이브러리를 불러옵니다. 이 라이브러리는 Node.js 환경에서 브라우저 자동화 및 웹 스크래핑을 위해 사용됩니다.
const puppeteer = require('puppeteer');

 

  • 비동기 함수 선언 및 실행
    • 비동기 함수가 즉시 실행되도록 선언하고 있습니다. Puppeteer의 대부분의 메서드는 비동기적으로 동작하므로 async/await 패턴을 사용합니다.
(async () => {

 

  • 브라우저 실행
    • puppeteer.launch 메서드를 사용해 브라우저 인스턴스를 실행합니다. headless: true 옵션은 브라우저를 UI 없이 백그라운드에서 실행하도록 합니다. 이는 일반적으로 빠르고 효율적인 크롤링을 위해 사용됩니다.
const browser = await puppeteer.launch({ headless: true });

 

  • 새로운 페이지 생성
    • 새로운 탭을 열기 위해 browser.newPage() 메서드를 사용합니다. 이 페이지는 이후 웹사이트에 접속하고 조작할 수 있는 컨텍스트가 됩니다.
const page = await browser.newPage();

 

  • 웹사이트로 이동
    • page.goto 메서드를 사용하여 주어진 URL로 이동합니다. waitUntil: 'networkidle2' 옵션은 네트워크 연결이 거의 없을 때까지(즉, 모든 주요 리소스가 로드될 때까지) 기다리도록 설정합니다.
await page.goto('https://coinness.com', { waitUntil: 'networkidle2' });

 

  • 페이지 컨텐츠 추출
    • page.evaluate는 브라우저 컨텍스트에서 실행되는 함수입니다. 이 함수는 DOM에서 특정 클래스를 가진 모든 요소들을 선택(querySelectorAll)하고, 각 요소의 텍스트(innerText)를 추출하여 배열로 반환합니다.
const texts = await page.evaluate(() => {
const childElements = document.querySelectorAll('.BreakingNewsContents-sc-glfxh-5.bULVI.omit'); 
return Array.from(childElements).map(child => child.innerText); });

 

  • 결과 출력
    • 앞에서 추출한 텍스트 배열을 콘솔에 출력합니다. 이 배열은 지정된 클래스의 모든 요소의 텍스트를 포함합니다.
console.log(texts);

 

  • 브라우저 종료
    • 모든 작업이 끝나면 browser.close() 메서드를 호출해 브라우저를 종료하여 리소스를 해제합니다.
await browser.close();