본문으로 건너뛰기

Puppeteer로 웹사이트 스크린샷을 자동화하는 방법

JavaScript로 Puppeteer를 사용해 웹사이트 스크린샷을 자동화합니다. 한 페이지, 전체 페이지, URL 일괄 캡처, 모바일 뷰포트를 재사용 가능한 스크립트로 다룹니다.

11분 분량웹사이트 캡처작성자: Temposhot Team

Puppeteer는 Chrome 팀이 관리하는 Node.js 라이브러리입니다. JavaScript API로 Chrome 또는 Firefox를 제어하며, 스크립트로 웹사이트 스크린샷을 찍을 때 자주 쓰입니다. 아래 예제는 다섯 줄짜리 캡처에서 시작해, 파일에서 URL을 읽고 페이지를 병렬로 실행하며 보고서를 쓰는 재사용 가능한 실행기로 발전합니다.

마지막 절은 같은 일괄 작업을 Mac의 Temposhot Website Capture 실행으로 보여 줍니다. 유지보수할 스크립트가 없습니다. 두 방식은 비슷한 파일을 만들며, 작업을 어디에서 실행하느냐에 따라 선택이 달라집니다.

Puppeteer가 적합한 도구인 경우

Puppeteer는 스크린샷이 이미 실행 중인 코드 안에 있어야 할 때 적합합니다.

  • 미리보기나 소셜 이미지를 렌더링하는 Node.js 서비스
  • 배포 후 페이지를 캡처하는 cron 작업 또는 CI 단계
  • 시각 기록도 함께 남기는 스크레이핑 작업
  • 이미 Chrome DevTools Protocol 기능을 사용하는 팀

Node.js 프로젝트를 유지보수하지 않는 사람이 하는 일회성 작업에는 덜 맞습니다.

Puppeteer가 적합하다는 여섯 가지 신호의 체크리스트. Node.js 프로젝트가 이미 있음, 캡처가 일정이나 CI에서 실행됨, 이미지 파일이 다른 프로그램이나 빌드에 쓰임, 팀이 스크립트 변경을 다른 코드처럼 검토함, 서버가 작업을 실행하며 데스크톱 앱용 디스플레이가 없음, 작업에 단순 URL 방문 이상의 브라우저 단계가 필요함.

스크린샷 스크립트용 Puppeteer 설치

mkdir site-shots && cd site-shots
npm init -y
npm install puppeteer

puppeteer 패키지는 설치 중에 호환되는 Chrome 빌드를 내려받습니다. 더 가벼운 puppeteer-core 패키지는 이 다운로드를 건너뛰고, 대신 설치된 브라우저의 경로를 요구합니다. 아래 스크립트는 .mjs 파일을 사용하므로 최상위 await를 쓸 수 있습니다.

puppeteer와 puppeteer-core 중 고르기

다운로드가 허용된 개발자 Mac에서는 puppeteer를 사용합니다. Chrome이 이미 설치된 CI 이미지나 브라우저 다운로드가 막힌 네트워크에서는 puppeteer-core를 사용합니다. 두 패키지의 API는 같으므로 스크립트는 바뀌지 않습니다. 브라우저가 사용자 지정 위치에 있을 때만 launch 호출에 executablePath가 필요합니다.

site-shots 프로젝트의 파일 트리. 패키지 파일, one과 run 스크립트, urls 텍스트 파일, 실행마다 날짜별 하위 폴더를 하나씩 가진 shots 폴더가 있음.

웹사이트 스크린샷 한 장 캡처

// one.mjs
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.setViewport({ width: 1440, height: 900 });
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
await page.screenshot({ path: 'example.png' });

await browser.close();

page.setViewport는 너비와 높이를 설정합니다. 같은 호출에 deviceScaleFactor: 2를 추가하면 Retina 디스플레이와 비슷하게 픽셀 밀도가 두 배인 이미지를 얻습니다.

설정이 만드는 결과

위 스크립트에 deviceScaleFactor: 2를 더하면 출력 크기가 고정됩니다. 숫자는 뷰포트와 배율에서 나옵니다.

한 페이지 스크립트의 설정. 뷰포트 1440 x 900 CSS 픽셀, 디바이스 배율 2, 네트워크 연결이 0개가 될 때까지 대기, 출력 PNG, 출력 크기 2880 x 1800 픽셀.

배율은 픽셀 수를 곱하고 CSS 크기는 그대로 둡니다. 그래서 출력은 각 방향에서 뷰포트의 두 배입니다. 배율 1의 1440 x 900 뷰포트는 1440 x 900 이미지를 만들며, 웹 미리보기에는 이 크기가 맞습니다. 배율은 고밀도 화면에서 선명한 이미지를 얻기 위한 설정이며, 그만큼 파일 크기가 두 배가 됩니다.

전체 페이지 스크린샷 캡처

await page.screenshot({ path: 'example-full.png', fullPage: true });

fullPage: true를 지정하면 이미지가 스크롤 가능한 문서 전체를 덮습니다. 파일을 작게 만들려면 JPEG 또는 WebP로 저장합니다.

await page.screenshot({ path: 'example.jpg', type: 'jpeg', quality: 80, fullPage: true });

quality는 0부터 100까지 값을 받으며 JPEG와 WebP에만 적용됩니다. 길이가 긴 페이지의 전체 페이지 스크린샷은 높이가 수만 픽셀에 이를 수 있으므로, JPEG를 쓰면 파일 크기를 관리하기 쉬운 경우가 많습니다.

긴 페이지의 크기

너비는 뷰포트 너비로 유지되고, 높이는 문서를 따릅니다. 긴 글은 이미지를 매우 높게 만들며, 아래 수치는 그 변화의 규모를 보여 줍니다.

1440픽셀 너비의 긴 글을 전체 페이지로 캡처한 통계 네 가지. 높이 12,000픽셀, 픽셀 수 1,730만, 3840 x 2160 프레임 픽셀 수의 2.1배, JPEG 품질 80 설정.

3840 x 2160 프레임은 약 830만 픽셀이므로, 예시 이미지는 4K 프레임의 약 두 배입니다. 높은 이미지는 한 번에 보기 어렵습니다. 화면이나 문서에 넣을 이미지라면 아주 긴 페이지를 clip으로 나눕니다.

한 구간 자르기

clip 옵션으로 한 영역을 저장합니다. 좌표는 뷰포트가 아니라 페이지 맨 위에서부터의 CSS 픽셀입니다.

await page.screenshot({
  path: 'example-pricing.png',
  clip: { x: 0, y: 2400, width: 1440, height: 900 },
});

한 번의 호출에서는 fullPage와 clip 중 하나만 사용합니다. 긴 페이지를 여러 파일로 나누려면 document.body.scrollHeight로 높이를 읽고, 구간마다 clip을 하나씩 만듭니다. 12000픽셀 페이지를 900픽셀 구간으로 자르면 14개 파일이 생기며, 마지막 파일에는 300픽셀만 담깁니다.

URL 실행기 만들기

// run.mjs
import { readFile, mkdir, writeFile } from 'node:fs/promises';
import puppeteer from 'puppeteer';

const urls = (await readFile('urls.txt', 'utf8'))
  .split('\n').map((l) => l.trim()).filter(Boolean);
const outDir = `shots/${new Date().toISOString().slice(0, 10)}`;
await mkdir(outDir, { recursive: true });

const browser = await puppeteer.launch();

async function shoot(url, index) {
  const page = await browser.newPage();
  try {
    await page.setViewport({ width: 1440, height: 900 });
    await page.goto(url, { waitUntil: 'networkidle2', timeout: 45000 });
    const path = `${outDir}/${String(index + 1).padStart(3, '0')}.jpg`;
    await page.screenshot({ path, type: 'jpeg', quality: 80, fullPage: true });
    return { url, path, ok: true };
  } finally {
    await page.close();
  }
}

URL마다 새 페이지를 열면 한 사이트의 충돌이 다음 사이트에 영향을 주지 않습니다. 날짜가 붙은 출력 폴더는 이전 실행 결과를 그대로 보존합니다.

이 실행기는 다섯 단계로 동작합니다. 아래 그림은 각 단계와 그 단계가 건드리는 파일 또는 프로세스를 순서대로 보여 줍니다.

다섯 상자의 흐름. urls.txt 읽기, 날짜 출력 폴더 만들기, 전체 실행에 브라우저 하나 띄우기, URL마다 자기 페이지에서 캡처, 모든 결과를 담은 report.json 쓰기.

URL 목록 정리

빈 줄, 주석, 중복 URL은 브라우저 시간을 낭비하며, 중복 URL은 같은 페이지의 파일을 하나 더 만듭니다. 아래 버전은 해시 기호로 시작하는 줄을 건너뛰고, 완전히 같은 중복을 제거하며, HTTP나 HTTPS가 아닌 주소를 버립니다. raw에는 앞 단계에서 읽은 파일 내용이 들어 있습니다.

const lines = raw.split('\n').map((l) => l.trim()).filter((l) => l && !l.startsWith('#'));
const urls = [...new Set(lines)].filter((l) => {
  try {
    const { protocol } = new URL(l);
    return protocol === 'http:' || protocol === 'https:';
  } catch {
    return false;
  }
});

Set은 문자열을 정확히 비교하므로 https://example.com과 https://example.com/은 서로 다른 두 URL로 남습니다. 거부된 줄도 기록합니다. htps://example.com 같은 오타는 45초 뒤의 타임아웃으로 나타나는 대신 실행 시작 시 로그에 나타납니다.

큰 일괄 작업의 번호 매기기

스크립트는 인덱스를 세 자리로 맞춥니다. 이 방식은 파일이 999개까지 올바르게 정렬됩니다. 인덱스 1000은 1000.jpg가 되고, 문자열 정렬에서는 100.jpg와 101.jpg 사이에 놓입니다. 대신 배치 크기에 맞춰 자릿수를 정합니다.

const width = String(urls.length).length;
const path = `${outDir}/${String(index + 1).padStart(width, '0')}.jpg`;

URL 1,250개 배치는 자릿수가 4가 되므로 첫 파일은 0001.jpg가 됩니다. 워커를 시작하기 전에 자릿수를 한 번 계산합니다.

큰 배치를 위한 동시 실행 추가

const LIMIT = 4;
const queue = [...urls.entries()];
const results = [];

async function worker() {
  while (queue.length) {
    const [i, url] = queue.shift();
    results.push(await shootWithRetry(url, i));
  }
}

await Promise.all(Array.from({ length: LIMIT }, worker));
await browser.close();

각 워커는 공유 큐에서 다음 URL을 가져갑니다. 4로 시작하고, 메모리를 확인한 뒤에만 한도를 올립니다. 열린 페이지마다 별도의 렌더러 프로세스를 쓰기 때문입니다.

스크립트는 한 브라우저에서 모든 페이지를 엽니다. 페이지는 기본적으로 브라우저의 캐시를 공유하고 쿠키도 공유합니다. 서로 관련 없는 공개 사이트의 일괄 작업에서는 문제가 없습니다. 한 사이트의 상태가 다음 사이트로 넘어가면 안 되는 실행에서는 browser.createBrowserContext()로 URL마다 컨텍스트를 하나씩 만들고, 캡처 후 닫습니다. 컨텍스트마다 메모리를 쓰므로, 이 선택은 동시 실행 한도와 함께 정합니다.

한도 고르기

한도는 동시에 렌더링되는 페이지 수를 정합니다. 한도가 낮으면 메모리 사용이 일정하지만 실행이 길어지고, 한도가 높으면 그 반대입니다. 아래 표는 페이지당 평균 약 6초가 걸리는 URL 200개 배치의 절충을 보여 줍니다.

페이지당 약 6초인 URL 200개에 대해 동시 실행 한도 1과 10을 비교함. 한 번에 한 페이지면 약 20분, 열 페이지면 약 2분과 렌더러 열 개의 메모리 비용이 듦.

이상적인 시간은 네트워크 대기와 실패가 없다고 가정합니다. 실제 사이트는 다르며, 타임아웃과 재시도가 시간을 더합니다. 대상 기기에서 URL 20개 배치를 두 가지 한도로 측정하고, Mac이 계속 반응하는 가장 높은 한도를 고릅니다.

모바일 스크린샷 캡처

Puppeteer는 KnownDevices를 통해 기기 디스크립터를 제공합니다.

import puppeteer, { KnownDevices } from 'puppeteer';

const page = await browser.newPage();
await page.emulate(KnownDevices['iPhone 13']);
await page.goto('https://example.com');

page.emulate는 뷰포트, 픽셀 비율, 터치 지원, 사용자 에이전트를 한 호출에서 설정합니다. 사용자 에이전트를 바꾸지 않고 모바일 너비만 필요하면 isMobile: true와 hasTouch: true를 지정해 setViewport를 호출합니다.

두 가지 모바일 설정 비교. 기기 디스크립터를 쓴 emulate는 뷰포트, 픽셀 비율, 터치 지원, 사용자 에이전트를 바꾸고, isMobile을 쓴 setViewport는 뷰포트와 터치 동작만 바꿈.

사이트가 사용자 에이전트에 따라 다른 마크업을 보내면 emulate를 쓰고, 레이아웃 너비만 중요하면 setViewport를 씁니다. 두 호출은 실행하는 페이지에만 적용되므로, 나중에 여는 두 번째 페이지에는 별도의 호출이 필요합니다.

데스크톱과 모바일을 섞은 배치에는 출력 세트마다 뷰포트가 하나씩 필요하며, 스크립트 하나당 하나가 아닙니다. 모바일 이미지는 shots/2026-04-10-mobile처럼 별도의 날짜 폴더에 두어, 두 세트의 파일 번호가 겹치지 않게 합니다. Temposhot Website Capture는 같은 목적으로 Mobile 크기를 390 x 844로 설정하며, 같은 실행 안에서 행마다 지정합니다.

에뮬레이션된 뷰포트 확인

캡처 전에 페이지에서 레이아웃 너비를 확인합니다. 잘못된 디스크립터는 모바일 크기 이미지 안에 데스크톱 레이아웃을 만듭니다. 아래 코드는 페이지가 보는 너비와 픽셀 비율을 보고합니다.

const seen = await page.evaluate(() => ({
  width: window.innerWidth,
  pixelRatio: window.devicePixelRatio,
}));
console.log(seen);

최근 Puppeteer 릴리스의 iPhone 13 디스크립터에서 너비는 390이어야 합니다. 픽셀 비율도 디스크립터에서 옵니다. 디스크립터 데이터는 릴리스마다 바뀌므로, 설치한 버전에서 값을 확인합니다.

지연 로딩 콘텐츠 처리

스크롤에 따라 로드되는 이미지는 탐색 직후에 찍은 캡처에서 빈 상태로 남습니다. 먼저 페이지를 스크롤합니다.

await page.evaluate(async () => {
  for (let y = 0; y < document.body.scrollHeight; y += window.innerHeight) {
    window.scrollTo(0, y);
    await new Promise((r) => setTimeout(r, 200));
  }
  window.scrollTo(0, 0);
});

지연 로딩 항목에서 이 패턴을 설명합니다.

스크롤에 걸리는 시간

루프는 단계마다 200밀리초를 기다리며, 각 단계는 뷰포트 높이만큼 움직입니다. 아래 예는 뷰포트 높이 900픽셀에서 높이 8000픽셀인 페이지입니다.

8000픽셀 페이지의 스크롤 타임라인. 0.0초에 0픽셀로 스크롤, 0.2초에 900픽셀, 1.6초에 7200픽셀, 1.8초에 캡처 전 맨 위로 복귀.

이 페이지는 9단계이므로 스크린샷 전에 1.8초가 더해집니다. 이미지가 천천히 로드되는 페이지는 단계마다 더 긴 대기가 필요하며, 무한 스크롤 페이지는 고정된 끝에 도달하지 않습니다. 무한 스크롤에서는 문서 높이 대신 고정된 단계 수 뒤에 멈춥니다.

컨테이너 안에서 스크롤

일부 레이아웃은 창이 아니라 내부 요소를 스크롤합니다. 그러면 위 루프는 움직임을 감지하지 못하고 페이지 아래쪽이 빈 상태로 남습니다. 대신 요소의 scrollTop을 바꾸고, 요소 자신의 scrollHeight와 clientHeight를 한계로 사용합니다. 실행 후에는 첫 프레임과 마지막 프레임을 비교합니다. 두 프레임이 같으면 페이지가 스크롤되지 않은 것이며, 원인이 컨테이너에 있음을 뜻합니다.

적절한 대기 전략 고르기

옵션반환 시점
loadload 이벤트가 발생함. 기본값임.
domcontentloadedHTML 파싱이 끝남.
networkidle0최소 500ms 동안 네트워크 연결이 없음.
networkidle2최소 500ms 동안 연결이 2개 이하임.

networkidle0은 폴링하거나 스트리밍하는 페이지에서 타임아웃될 수 있습니다. networkidle2는 그런 백그라운드 트래픽을 허용합니다. 페이지에 명확한 준비 신호가 있으면 그 요소에 대한 page.waitForSelector가 가장 안정적입니다. 기본 탐색 타임아웃은 30초입니다.

대시보드 페이지의 준비 신호 체크리스트. 메인 차트 컨테이너가 DOM에 있음, 로딩 스피너가 제거됨, 마지막 데이터 행이 보임, 웹 폰트 로드가 끝남, 동의 배너가 닫히거나 숨겨짐.

페이지가 내용이 준비됐을 때만 설정하는 신호를 하나 고릅니다. 헤더처럼 모든 페이지 로드에 존재하는 셀렉터는 그 아래의 데이터가 준비됐는지 증명하지 못합니다.

대기를 고르기 전에 측정

대기 전략을 정하기 전에 URL마다 탐색 시간을 잽니다. 아래 값은 load 이벤트가 발생할 때까지의 시간입니다.

const started = Date.now();
await page.goto(url, { waitUntil: 'load', timeout: 45000 });
const loadMs = Date.now() - started;

loadMs를 각 URL 옆의 보고서에 기록합니다. 대부분의 페이지가 몇 초 안에 로드되면 기본 대기로 충분합니다. 일부 페이지 그룹이 타임아웃 근처에 있으면 그 URL은 domcontentloaded로 바꾸고 셀렉터를 기다리며, 변경을 확인할 수 있도록 보고서를 남깁니다.

재시도와 보고서 추가

async function shootWithRetry(url, i, tries = 3) {
  for (let attempt = 1; attempt <= tries; attempt++) {
    try {
      return await shoot(url, i);
    } catch (error) {
      if (attempt === tries) return { url, ok: false, error: error.message };
    }
  }
}

// after Promise.all in run.mjs
await writeFile(`${outDir}/report.json`, JSON.stringify(results, null, 2));

보고서에는 모든 URL이 파일 경로 또는 오류와 함께 나열됩니다. 실패한 항목은 두 번째 실행을 위해 urls.txt에 다시 넣습니다.

보고서에서 재시도 목록 만들기

보고서가 있으면 두 번째 실행은 수작업 복사가 아니라 필터가 됩니다. 아래 jq 명령은 실패한 URL을 새 파일에 씁니다.

jq -r '.[] | select(.ok == false) | .url' shots/2026-04-10/report.json > urls-retry.txt

두 번째 실행에서는 스크립트가 urls-retry.txt를 읽도록 합니다. 스크립트는 출력 폴더를 날짜로 이름 짓기 때문에, 같은 날 두 번째 실행은 같은 폴더에 씁니다. 그러면 같은 번호의 파일이 첫 실행의 이미지를 덮어씁니다. 두 번째 실행 전에 outDir에 -retry 같은 접미사를 붙여 두 실행이 모두 폴더에 남게 합니다.

최악의 경우 실행 시간

느린 사이트는 모든 재시도를 소진할 수 있습니다. 타임아웃과 재시도 횟수가 URL 하나의 최악의 경우를 정하고, 워커 수는 그 비용을 나눠 가집니다. 아래 그림은 스크립트의 값을 사용합니다.

최악의 경우 통계 네 가지. URL마다 3회 시도, 시도마다 45초, 모든 시도가 타임아웃되면 URL당 135초, 워커 4개로 URL 100개가 모두 타임아웃될 때 약 56분.

정상적인 배치에서 최악의 경우는 거의 일어나지 않지만, 상한선을 정해 줍니다. 타임아웃이 많은 실행도 다음 실행이 시작하기 전에 끝나도록 작업 일정을 잡습니다.

바뀔 수 있는 오류만 재시도

탐색 타임아웃이나 끊어진 연결은 두 번째 시도에서 성공할 수 있습니다. 페이지가 완전히 로드되었지만 기대한 셀렉터가 없는 경우, 또는 404 상태를 반환하는 페이지는 보통 같은 방식으로 다시 실패합니다. 첫 번째 그룹은 재시도하고, 두 번째 그룹은 한 번 기록합니다. 위의 shootWithRetry 함수는 모든 오류를 재시도하므로, 고정된 실패는 보고서에 나타나기 전에 타임아웃 3회를 치릅니다.

실용적인 폴더 구조

site-shots/
  run.mjs
  urls.txt
  shots/
    2026-04-10/
      001.jpg
      002.jpg
      report.json

실행 날짜마다 폴더를 하나, 폴더마다 보고서를 하나 둡니다. 데이터베이스 없이 나중에 실행을 비교하기에는 이 정도 구조면 충분합니다.

자주 하는 실수

  1. 모든 사이트에 networkidle0을 사용함. 분석 도구나 채팅 위젯이 있는 페이지는 네트워크가 끝내 안정되지 않습니다.
  2. 페이지를 열어 둠. 메모리가 쌓여 프로세스가 느려지거나 충돌합니다.
  3. 너무 많은 페이지를 동시에 실행함. 노트북에서 한도 20은 실행을 빠르게 하기보다 타임아웃을 더 자주 만드는 경우가 많습니다.
  4. 동의 오버레이를 캡처함. 셀렉터로 거부 버튼을 클릭하거나 page.addStyleTag로 배너를 숨깁니다.
  5. 사이트 이용 약관을 확인하지 않음. 자동화된 캡처는 실제 요청을 보냅니다. 사이트마다 이용 약관을 확인하고 요청 빈도를 낮게 유지합니다.

증상별 문제 해결

증상가능한 원인해결
전체 페이지 이미지의 빈 영역지연 로딩 콘텐츠가 화면에 들어오도록 스크롤되지 않음캡처 전에 스크롤 단계를 실행
goto에서 타임아웃페이지가 대기 이벤트에 도달하지 않음셀렉터를 기다리거나 domcontentloaded로 바꿈
모든 URL에 같은 이미지탐색이 끝나기 전에 캡처함각 페이지에서 goto를 await하고, URL마다 새 페이지를 엶
이미지가 예상의 두 배 크기deviceScaleFactor가 2임배율을 제거하거나 1로 설정
긴 실행 동안 메모리가 늘어남캡처 후에도 페이지가 열려 있음finally 블록에서 각 페이지를 닫고 동시 실행을 제한
이미지에 동의 배너가 나타남배너를 처리하지 않음셀렉터로 거부 버튼을 클릭하거나 배너를 숨김
스크린샷 스크립트의 do와 dont 목록. do는 각 페이지를 닫고, 동시 실행을 제한하고, 페이지가 설정한 준비 신호를 기다리고, URL마다 항목 하나가 있는 보고서를 남김. dont은 networkidle0을 기본 대기로 쓰지 않고, 실행 사이에 같은 출력 폴더를 재사용하지 않음.

Puppeteer 스크린샷 스크립트의 대안

  • Playwright는 비슷한 API를 제공하며 WebKit도 구동합니다. Playwright로 웹사이트 스크린샷을 자동화하는 방법을 참고합니다.
  • 호스팅 스크린샷 API는 브라우저를 대신 실행하고 HTTP로 이미지를 반환합니다.
  • 브라우저 확장 프로그램인 Temposhot 확장 프로그램은 활성 탭의 전체 페이지 PNG를 한 장 저장합니다.
  • Temposhot Website Capture는 코드 없이 Mac에서 붙여 넣은 URL 목록을 실행합니다. Desktop 1920×1080, Tablet 768×1024 또는 Mobile 390×844 크기를 고르며, 행마다 0-60초의 지연을 설정합니다.

스크립트가 가치가 없는 경우

스크립트는 처음 버전이 보여 주는 것보다 시간이 지나면 비용이 더 듭니다. 사이트가 바뀔 때마다, Node.js를 업그레이드할 때마다, Chrome이 업데이트될 때마다 수정이 필요할 수 있습니다. 목록이 자주 바뀌는 월간 작업은 URL 목록과 행 설정이 한 창에 있는 Website Capture에서 비용이 적게 듭니다. 이미지가 빌드 단계에 쓰이거나, CI 파이프라인이 실행해야 하거나, 방문과 캡처 이상의 단계가 필요하면 스크립트를 유지합니다.

같은 일괄 작업을 Temposhot Website Capture에서 실행

Temposhot Website Capture는 이 글의 일괄 작업을 스크립트 없이 처리합니다. 아래 설정은 1440 x 900 전체 페이지 캡처의 실행기와 맞고, Temposhot이 행마다 노출하는 대기 및 차단 옵션을 함께 사용합니다.

Temposhot Website Capture 일괄 작업의 설정. Desktop 기기, Full page 영역, Network idle 대기, 2초 지연, 쿠키 배너 거부, 광고와 추적기 차단 켜짐, JPEG 품질 80, 동시 브라우저 4개.

Temposhot에서 Desktop 크기는 1920 x 1080이므로, 스크립트의 1440 x 900과 의도적으로 다릅니다. 두 결과가 같아야 한다면 양쪽에 같은 뷰포트를 설정합니다. Temposhot 실행은 결과 막대의 ZIP, Images 또는 PDF로 끝나며, 선택한 프레임을 내보냅니다.

Temposhot Website Capture에서 URL 일괄 작업을 실행하는 다섯 단계. Bulk insert로 목록 붙여 넣기, Run Settings에서 설정, 캡처 시작, 실패한 행에서 재시도, 결과 막대에서 ZIP으로 내보내기.

실행 중에는 각 행에 상태가 표시됩니다. 예를 들어 Capturing 또는 Capture failed입니다. 실패한 행은 나머지 일괄 작업을 다시 시작하지 않고 그 행만 따로 재시도할 수 있습니다.

행 상태 비교. Capture pending은 빈 브라우저 슬롯을 기다림, Capturing은 페이지를 로드하거나 캡처함, Capture complete는 스크린샷이 저장됨, Capture failed는 스크린샷이 만들어지지 않음을 뜻함.

FAQ

Puppeteer는 Firefox와 함께 작동합니까?

예. 최근 버전은 Chrome뿐 아니라 Firefox도 실행할 수 있습니다. 가장 널리 쓰이는 선택지는 여전히 Chrome입니다.

Puppeteer로 WebP 스크린샷을 저장할 수 있습니까?

예. 스크린샷 옵션에 type: 'webp'를 설정합니다. quality 값은 JPEG와 마찬가지로 WebP에도 적용됩니다.

일부 사이트에서 page.goto가 타임아웃되는 이유는 무엇입니까?

페이지가 30초 안에 선택한 대기 이벤트에 도달하지 못했기 때문입니다. networkidle2 또는 load로 바꾸거나, timeout을 늘리거나, 대신 셀렉터를 기다립니다.

전체 페이지 이미지의 일부가 빈 이유는 무엇입니까?

콘텐츠는 화면에 스크롤될 때 로드됩니다. 캡처 전에 지연 로딩 섹션의 스크롤 단계를 실행하고, 마지막 행이 나타날 때까지 기다립니다.

한 번의 실행으로 URL을 몇 개까지 처리할 수 있습니까?

한도는 코드가 아니라 메모리와 시간에서 나옵니다. 계획한 동시 실행 수준에서 URL 20개 배치를 측정하고, 메모리를 지켜본 뒤 규모를 늘립니다. Temposhot Website Capture는 Concurrent browsers를 1에서 10까지 설정할 수 있으며, 기본값은 4입니다.

스크린샷 출력을 Git에 넣어야 합니까?

아니요. 이미지와 보고서는 실행마다 커지는 빌드 산출물입니다. urls.txt와 스크립트는 버전 관리에 두고, 출력 폴더는 크기가 맞는 곳에 저장합니다.

참고 자료

노코드 웹사이트 스크린샷 자동화가 필요합니까?

Temposhot Website Capture는 같은 종류의 URL 일괄 작업을 Mac에서 로컬로 실행하며, 행마다 설정이 있고 관리할 스크립트가 없습니다. 웹사이트 스크린샷 자동화 페이지 또는 캡처 옵션 가이드를 참고합니다.

puppeteerwebsite-captureautomationnodejs

여기서 사용한 용어: full page screenshot, headless browser, playwright, puppeteer, screenshot api, screenshot automation, viewport screenshot

반복되는 스크린샷을 완성된 결과물로 만듭니다

Temposhot은 타이머 또는 클릭할 때마다 캡처하고, 결과를 PDF, 이미지, ZIP 또는 MP4로 내보냅니다.

관련 글