How to download all images from a website, full size, in one ZIP
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.
- 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.
- Set a minimum size (for example 300 x 300 px) so icons, avatars and tracking pixels are skipped.
- Run the list through a bulk downloader and choose one ZIP (a folder per page) or one ZIP per page.
- Open the per-image table (format, width, height, bytes, alt text) to spot missing alt text or heavy files.
- 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.| Field | Value |
|---|---|
| source | srcset (the largest size, not the page's copy) |
| format | jpeg |
| width x height | 1920 x 1200 |
| bytes | 1,408,399 |
| alt | Sunita Rai at WordCamp Asia |
| fileName | 002-wordpress.org_news/0002-sunita-rai-featured-img.jpg |
Source: Picpail (Apify Actor cybermax/bulk-image-downloader) README, real run on 24 Sep 2026
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: Every image on a page, full size, one ZIP
$0.0008 per image, duplicates and skips freePicpail: 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.