ScreenshotNeo

BlogHow-to

How to Screenshot Shopify Product Pages in Bulk with Apify

Capture Shopify product pages in bulk with Apify’s Website Screenshot Generator. Configure full-page or viewport shots, retrieve files, and troubleshoot failures.

By the ScreenshotNeo team4 October 20268 min read

To screenshot Shopify product pages in bulk with Apify, run the community-maintained Website Screenshot Generator Actor with one public product-page URL per entry in startUrls. Choose a capture mode, image or PDF format, viewport, and wait condition; then retrieve the files from the run’s key-value store and check each dataset row for errors. The Actor captures rendered pages, so it is appropriate when you need visual records rather than product fields.

This guide uses the Actor’s documented inputs and limits. It is maintained by the community, not presented as an official Apify-built Actor. [Actor listing]

1. Prepare a URL list

Collect the public product-page URLs you are authorized to capture. Add each URL as its own object under startUrls. Use the canonical product URL where possible so repeated runs target the same page.

{
  "startUrls": [
    { "url": "https://example-store.com/products/linen-shirt" },
    { "url": "https://example-store.com/products/canvas-tote" },
    { "url": "https://example-store.com/products/ceramic-mug" }
  ],
  "screenshotType": "fullPage",
  "outputFormat": "png"
}

Replace the example domains and paths with your actual public product URLs. This input shape illustrates the core batch: URL objects plus capture options. Actor runs accept structured JSON input, can be started manually or through an API, and store results in platform outputs such as datasets. [Apify get started]

2. Configure the capture

Setting Choose it when What to watch
screenshotType: fullPage You need the complete scrollable product page. Very tall pages can exceed the configured maximum image height and be clipped.
screenshotType: viewport You need only the initially visible browser area. Below-the-fold content will not be represented.
Viewport width and height You need a consistent visual comparison between products or runs. Responsive layouts change with viewport dimensions; use the same dimensions for comparable captures.
deviceScaleFactor and mobile viewport settings You need a higher-density image or a mobile layout. Use consistent settings across the batch. The listing documents these controls.
outputFormat: png, jpeg, or pdf Select the output that fits your archive or review workflow. PDF uses print layout and ignores screenshot mode and element selector settings.
CSS element selector You need a visible region such as main, .product-card, or #pricing. The selected element must be visible within the timeout. Selector capture applies to image captures, not PDF.
Wait condition You need to balance speed with completion of page rendering. Try domcontentloaded for fast static pages, load for regular pages, or networkidle where later network activity matters.

For most product-page archives, start with full-page PNG captures, a fixed viewport, and load. If images or other content are still missing, test one URL with a small added delay or networkidle before applying that behavior to the full batch. Different wait conditions can change both completion and runtime. The Actor listing documents the formats and options above. [Website Screenshot Generator configuration]

3. Run the batch from the Apify API

You can run the Actor from the Apify Console or call its run endpoint. The API token is specific to your Apify account; keep it in an environment variable and do not publish it in source code. The endpoint pattern below follows the Actor listing’s API example. [Actor API example]

cURL

export APIFY_TOKEN='YOUR_APIFY_TOKEN'

curl -X POST \
  "https://api.apify.com/v2/acts/fetch_cat~website-screenshot-generator/runs?token=${APIFY_TOKEN}" \
  -H 'Content-Type: application/json' \
  -d '{
    "startUrls": [
      {"url":"https://example-store.com/products/linen-shirt"},
      {"url":"https://example-store.com/products/canvas-tote"}
    ],
    "screenshotType":"fullPage",
    "outputFormat":"png"
  }'

Python

This example uses the Apify client library and an environment variable for the token. Install the client with pip install apify-client. The Actor listing documents the client workflow of running with input and listing the default dataset. [Actor client examples]

import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("fetch_cat/website-screenshot-generator").call(run_input={
    "startUrls": [
        {"url": "https://example-store.com/products/linen-shirt"},
        {"url": "https://example-store.com/products/canvas-tote"},
    ],
    "screenshotType": "fullPage",
    "outputFormat": "png",
})

if not run:
    raise RuntimeError("Actor run did not return run details")

items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
for item in items:
    print(item)

Node.js

Install the Apify client with npm install apify-client. This example starts the Actor, waits for it to finish, and prints its dataset rows. [Actor client examples]

import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/website-screenshot-generator').call({
  startUrls: [
    { url: 'https://example-store.com/products/linen-shirt' },
    { url: 'https://example-store.com/products/canvas-tote' },
  ],
  screenshotType: 'fullPage',
  outputFormat: 'png',
});

if (!run) throw new Error('Actor run did not return run details');
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) console.log(item);

4. Retrieve and verify the screenshot files

Successful dataset rows include page metadata and a screenshot or PDF file key or URL. The Actor listing says each successful row includes a file URL, and the file is also stored in the run’s key-value store. Inspect the row’s status, final URL, error fields, and file reference before treating a batch as complete. A run can return partial results when individual pages fail or the capture time budget is reached. [Actor output and limits]

  1. Open the completed run in Apify Console and inspect its default dataset.
  2. Confirm each input URL has a corresponding successful row and file reference.
  3. Review failed rows, final URLs, and error details; redirecting product URLs may land somewhere unexpected.
  4. Download or process files from the key-value store using the file keys or URLs returned by the Actor.
  5. For recurring captures, keep the URL list and capture configuration under version control or in a stable job definition.

5. Make repeat runs comparable

Use the same URL normalization, viewport, device scale factor, output format, wait behavior, and cookie state whenever you compare captures over time. Store the capture date alongside the files. A page may still render differently because of location, consent state, responsive behavior, bot detection, or changes to the store; the workflow does not guarantee identical output between runs. Apify supports scheduled Actor runs generally, but scheduling does not guarantee that a particular Shopify page will render identically each time. [Apify get started]

6. Understand access limits and responsible use

The Actor describes its scope as publicly accessible HTTP/HTTPS pages. Private, login-gated, paywalled, or bot-blocked pages may fail or show limited content. It rejects private, loopback, link-local, and reserved network destinations. Do not attempt to bypass authentication, paywalls, or other access controls. Confirm you have permission for the capture and intended downstream use, and follow the target site’s terms, Apify’s terms, and applicable laws. [Actor scope and responsible-use notes]

7. Troubleshoot incomplete or failed captures

Symptom Likely cause What to try
No output for a URL The page is private, blocked, unavailable, or failed during navigation. Test that URL by itself; inspect the dataset status, final URL, and error fields. Use only pages you can access legitimately.
Images or product details are missing The page loads key content after the initial document event. Start with one URL, use load, then add a small delay or try networkidle.
Selector capture is empty The selector does not match, or the matched element is not visible before timeout. Check the selector against the rendered page and choose a visible element; increase the opportunity for the page to render by adjusting the wait behavior.
Full-page image is clipped The page exceeds the configured maximum capture height. Check whether the output row marks truncated: true. Use viewport captures or another suitable way to divide the visual record.
PDF differs from the screen view PDF uses print layout, not the configured screenshot mode. Use PNG or JPEG if the on-screen rendering is the required evidence; treat PDF as a print-layout document.
Consent banner, newsletter popup, or chat widget covers content The interface is part of the page state and may remain visible in the capture. There is no universal method that reliably removes every consent interface. For a deterministic capture, use a known site-specific selector if the workflow allows it, and do not misrepresent the resulting state.
Some pages succeed and others fail in one run Per-page rendering and access vary, or the run reached its capture time budget. Use the partial output; retry only failed URLs individually and inspect their error details.

For a page that appears incomplete, the listing recommends beginning with one URL, selecting load, adding a small delay, and checking status, final URL, and error fields. [Troubleshooting guidance]

8. Performance and cost considerations

Bulk capture is convenient, but each page must render in a browser, so the time required depends on the pages and their loading behavior. The cited listing does not provide a guaranteed completion time, success rate, or fixed maximum number of pages per run. Large images, full-page height, and waits for late network activity can affect runtime. Begin with a small representative batch, verify the output, and expand while monitoring partial failures.

The listing showed a price of from $7.00 per 1,000 captures when accessed on October 3, 2026. This is a volatile listed price, not a guaranteed total-cost estimate; check the listing and your account’s current charges before planning a batch. [Current Actor listing]

9. Screenshots versus Shopify product data

A screenshot preserves rendered appearance. A Shopify product-data scraper instead returns structured fields such as titles, prices, variants, images, descriptions, and availability. The Apify Store’s Shopify Products Scraper is designed for that data extraction use case; it does not provide the visual screenshot output this guide covers. Use a screenshot workflow for visual records, and a data scraper when the task is catalog analysis or field monitoring. These deliverables complement each other but are not interchangeable. [Shopify Products Scraper]

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. A single GET request captures a page as PNG, JPEG, WebP, or PDF. Its API and MCP options are documented at ScreenshotNeo docs.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://example-store.com/products/linen-shirt \
  -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={
        "access_key": "YOUR_API_KEY",
        "url": "https://example-store.com/products/linen-shirt",
    },
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://example-store.com/products/linen-shirt',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. The API also supports bulk capture of up to 100 URLs per call. Sign up for 1,000 free screenshots a month, with no card.

FAQ

Can I capture all products from a Shopify store automatically?

This Actor workflow takes the URLs you provide in startUrls. It does not imply automatic discovery of every product URL in a store; prepare the URL list you need to capture.

Can I use a screenshot as a reliable record of the exact page shown to every shopper?

No. Location, viewport, cookie state, and bot detection can affect rendering. Record the capture settings and date, and treat the image as evidence of that particular capture session.

Will a product-data scraper give me screenshots too?

No. It returns structured catalog fields. Use a browser screenshot tool when the required output is a rendered image or PDF.

Can I use a selector with PDF output?

The listing says PDF uses print layout and ignores screenshot mode and element selector settings. Choose an image format for selector-based capture.