Skip to content
Search/
CyberMax › Answers

How to download all images from a website, full size, in one ZIP

Updated 2026-11-10 · Data and API builders · by CyberMax

Short answer

A browser save keeps the thumbnails it loaded. For full-size originals from many pages, send the URLs to a bulk image downloader: Picpail on Apify reads img, srcset, lazy-loaded and CSS images, swaps thumbnails for originals, removes duplicates and returns one ZIP plus a row per image, at $0.0008 per image.

  1. List the pages you want: product pages, category pages, a gallery, a blog archive (one URL per line). Direct image URLs can go in the same list.
  2. Set a minimum size (for example 300 x 300 px) so icons, avatars and tracking pixels are skipped.
  3. Run the list through a bulk downloader and choose one ZIP (a folder per page) or one ZIP per page.
  4. Open the per-image table (format, width, height, bytes, alt text) to spot missing alt text or heavy files.
  5. Check the licence before you reuse any image you did not create.

Copy-paste code

Python (pip install apify-client): a list of pages in, one ZIP link out

import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("cybermax/bulk-image-downloader").call(run_input={
    "urls": ["https://books.toscrape.com/", "https://wordpress.org/news/"],
    "minWidth": 300, "minHeight": 300,   # skip icons and thumbnails
    "output": "zip",                      # or zipPerPage, files, list
})
out = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("OUTPUT")["value"]
print("ZIP:", out["zips"][0]["url"])
for img in client.dataset(run["defaultDatasetId"]).iterate_items():
    if img.get("type") == "image":
        print(img["width"], img["height"], img["format"], img.get("alt") or "(no alt)", img["imageUrl"])

JavaScript / Node (npm i apify-client)

import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('cybermax/bulk-image-downloader').call({
  urls: ['https://books.toscrape.com/'],
  minWidth: 300,
  formats: ['jpeg', 'png', 'webp'],
});
const { value } = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('OUTPUT');
console.log('ZIP:', value.zips[0].url);

No code: n8n, Make or Zapier

n8n: HTTP Request node (or the Apify node, action "Run an Actor and get dataset")
Method:  POST
URL:     https://api.apify.com/v2/acts/cybermax~bulk-image-downloader/run-sync-get-dataset-items
Auth:    Header Auth  ->  Authorization: Bearer <your Apify token>
Body:    JSON  {"urls": ["https://example.com/gallery"], "minWidth": 300, "output": "zip"}
Output:  one n8n item per result row, ready for Google Sheets / Airtable / a Slack message

Make:    Apify app -> "Run an Actor" (Actor: cybermax/bulk-image-downloader, wait for finish = yes)
         -> Apify "Get Dataset Items" (dataset = the run's defaultDatasetId) -> Google Sheets "Add a Row"
Zapier:  Apify app -> action "Run Actor" (cybermax/bulk-image-downloader, input JSON as above)
         -> trigger "Finished Actor Run" -> "Fetch Dataset Items" -> your app
Runs longer than 5 minutes: start with POST /v2/acts/cybermax~bulk-image-downloader/runs and read the dataset when the run finishes.

From an AI agent (MCP)

# Any MCP client (Claude Desktop, Claude Code, Cursor, VS Code): Apify's hosted MCP server
{
  "mcpServers": {
    "bulk-image-downloader": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.apify.com/?tools=cybermax/bulk-image-downloader",
               "--header", "Authorization: Bearer ${APIFY_TOKEN}"],
      "env": { "APIFY_TOKEN": "<your Apify token>" }
    }
  }
}
# The agent sees one tool, cybermax--bulk-image-downloader, with the Actor's input schema.
One real dataset row (wordpress.org/news/, 24 Sep 2026)
FieldValue
sourcesrcset (the largest size, not the page's copy)
formatjpeg
width x height1920 x 1200
bytes1,408,399
altSunita Rai at WordCamp Asia
fileName002-wordpress.org_news/0002-sunita-rai-featured-img.jpg

Source: Picpail (Apify Actor cybermax/bulk-image-downloader) README, real run on 24 Sep 2026

Run Picpail on ApifyPixkiln: convert them to WebP

Why "Save page as" misses the full-size images

Most sites send a small image first and list larger ones in srcset, load images only when you scroll (lazy loading), or put photos in CSS backgrounds. A browser save keeps what was rendered, so you get 300 px product thumbnails instead of the 2000 px originals.

A bulk downloader reads the page source instead: every srcset candidate, data-src and data-lazy attributes, CSS url() backgrounds and og:image, then asks the CDN (Shopify, WordPress, Wikimedia and similar) for the original file.

Download images from a list of URLs or a whole site section

Put every page in the urls list: category pages, product pages or the pages of a sitemap. Set sameDomainOnly to skip ads and third-party trackers, urlPattern to keep only paths such as /products/, and excludeUrlPattern to drop logo|icon|sprite files.

Run it on a schedule to get only new images

Turn on monitor mode and add an Apify Schedule (daily or weekly): each run returns only images that were not delivered before, such as new products in a category or a changed homepage banner. Images you already have are skipped and not charged.

Convert the images to WebP or AVIF next

Picpail keeps each file in its original format and size. To publish them on a store or a fast page, run Pixkiln on the Picpail dataset (output "list"): every image is converted to WebP or AVIF, resized to your max width and stripped of EXIF in one ZIP, at $0.0015 per image.

Good to know

Price on Apify: $0.0008 per image delivered ($0.80 per 1,000), plus $0.0001 per MB for the part of a very large file above 2 MB. Duplicates, filtered images and failed downloads are free. Apify's free plan includes $5 of usage each month.

Pages that build everything with JavaScript after load may return a page-error row with the reason; those rows are free.

Picpail icon

Picpail: Every image on a page, full size, one ZIP

$0.0008 per image, duplicates and skips free

Picpail: every image on each page, full size, in one ZIP with a row per image. $0.0008 per image delivered; duplicates, filtered and failed images are free.

Runs on your own Apify account, pay per result; failed results are not charged.

Questions

Is it legal to download images from a website?

Saving publicly visible images is what a browser does, but reusing them needs the owner's permission or a licence. This is not legal advice.

How do I get the full-size image instead of the thumbnail?

Use a tool that reads srcset and asks the CDN for the original. Picpail does this by default (upgradeToOriginals).

Can I download images from many pages at once?

Yes: list the pages (hundreds are fine) and you get one ZIP with a folder per page, or one ZIP per page.

Can an AI agent use it?

Yes. Apify's MCP server exposes it as the tool cybermax--bulk-image-downloader, so Claude, Cursor or any MCP client can call it with your Apify token.

Why not a free browser extension?

For one page, an extension is fine. Extensions save what the browser shows (often thumbnails), one tab at a time; a bulk downloader works through a list, fetches originals and returns sizes and alt text.

Free: the Free API Starter Kit

Copy-paste calls for 4 APIs with free daily tiers (CVE priority, VIN recalls, US duty rates, email checks), then 5 short emails on KEV/EPSS, MCP and free data.

You get one email to confirm first. Then the kit, and 5 short emails over two weeks. One-click unsubscribe in every email; we never share your address.

Compare the options

Bulk image downloaders compared: per image or per page, and what you getPicpail vs two bulk image downloaders on Apify: live prices (per image vs per page URL), full-size originals,

Related answers

How to convert images to WebP in bulk, from a list of URLsConvert hundreds of JPEG and PNG images to WebP or AVIF in one run: resize, strip EXIF, get one ZIP and the byHow to find a company's website from its name, in bulkTurn a list of company names into official website domains with a confidence score and evidence. Get the PythoHow to find the contact email, phone and socials for a list of company domainsGet each company's published email, phone, socials and contact page from its own site, for a whole list of dom