Picpail — Bulk Image Downloader: All Images from URLs to ZIP avatar

Picpail — Bulk Image Downloader: All Images from URLs to ZIP

Pricing

Pay per event

Go to Apify Store
Picpail — Bulk Image Downloader: All Images from URLs to ZIP

Picpail — Bulk Image Downloader: All Images from URLs to ZIP

Download all images from web pages or image URLs into one ZIP, full-size originals instead of thumbnails: img, srcset, lazy-load, CSS, og:image. Real format and pixel size, duplicate removal, size/format filters, monitor mode. $0.0005 per image; duplicates and skips free.

Pricing

Pay per event

Rating

0.0

(0)

Developer

CyberMax

CyberMax

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

Share

Picpail: Bulk Image Downloader — All Images from URLs to ZIP

Download all images from any web page, or a list of image URLs, into one ZIP. Picpail finds every picture a visitor would see or click through to (<img>, srcset, lazy-load attributes, <picture>, CSS backgrounds, og:image, JSON-LD product images, gallery links to originals), swaps thumbnails for the full-size originals on Shopify, WordPress, Wikimedia, Cloudinary, Wix, Squarespace, Contentful and imgix, and downloads each file once. Every image is checked from its bytes (real format, width and height), duplicates are dropped by SHA-256, and you get a ZIP with a folder per page plus one data row per image. $0.50 per 1,000 images; duplicates, filtered-out images and failures are free.

Use it for: product photo downloads for a catalogue or marketplace migration, competitor image audits, backing up a site's media before a redesign, building image datasets, grabbing every photo from a gallery or blog post, and checking alt text across pages.

Why Picpail

PicpailTypical image downloader
Thumbnails → full-size originalsYes (Shopify, WordPress, Wikimedia, Cloudinary, Wix, Squarespace, Contentful, imgix)No: you get the 300 px copy the page shows
Lazy-loaded images (data-src, data-srcset, data-lazy-src …)YesOften missed
Real format, width, height, bytes, SHA-256 per imageYes, read from the fileGuessed from the HTML, or none
Duplicates removedBy URL and by file contentRarely
Filters (min width/height, formats, file size, URL regex, same site)Yes; filtered images are free and big files are cut short after the headerFew
One ZIP, split into parts for big jobsYes, streamed to disk (steady memory on any job size)Varies
Monitor mode (only new images since the last run)YesNo
Price$0.0005 per image$0.00089–$0.002 per image, or $0.07 per page URL

Benchmark (Apify, 24 Sep 2026, same 3 pages: books.toscrape.com, wordpress.org/news, an Allbirds product page):

ActorResultTimePrice for this job*
Picpail67 images, one 18 MB ZIP + a row per image (format, size, SHA-256, alt)4.2 s$0.034
getascraper/bulk-image-downloader72 files (the same pictures; 5 WordPress photos fetched twice at two sizes), no ZIP6.7 s$0.064
onescales/bulk-image-downloaderone 18 MB ZIP, no per-image data36.7 s$0.21 (free tier, $0.07 per URL)
crawlerbros/website-image-scraperimage URLs only (no files), every srcset size listed separately3.3–6.4 s per page$0.20

* Each Actor's published price for the Apify free tier on 24 Sep 2026. With full-size originals switched on (the default, added after this benchmark), the Allbirds page returns 2000–4000 px product photos instead of 300 px copies.

Ready-made inputs (first try in one click)

Every product image on a page, as one ZIP (the Store's default input; skips icons and tiny images):

{ "urls": ["https://books.toscrape.com/"], "minWidth": 100, "minHeight": 100 }

Only JPEG/PNG/WebP images, as a metadata list (links, sizes, formats) instead of a ZIP:

{ "urls": ["https://books.toscrape.com/"], "output": "list", "formats": ["jpeg", "png", "webp"], "minWidth": 100 }

Watch a page and download only new images each run (pair with a daily Schedule):

{ "urls": ["https://books.toscrape.com/"], "monitor": true, "monitorKey": "books-home" }

Example

Input:

{
"urls": [
"https://books.toscrape.com/",
"https://wordpress.org/news/",
"https://www.allbirds.com/products/mens-tree-runners"
],
"minWidth": 100,
"minHeight": 100
}

One dataset row per image:

{
"type": "image",
"pageUrl": "https://wordpress.org/news/",
"pageTitle": "WordPress News – The latest news about WordPress and the WordPress community",
"imageUrl": "https://i0.wp.com/wordpress.org/news/files/2024/01/sunita-rai-featured-img.jpg?ssl=1",
"pageImageUrl": "https://i0.wp.com/wordpress.org/news/files/2024/01/sunita-rai-featured-img.jpg?w=1920&ssl=1",
"source": "srcset",
"alt": "Sunita Rai at WordCamp Asia",
"format": "jpeg",
"mimeType": "image/jpeg",
"width": 1920,
"height": 1200,
"bytes": 1408399,
"sha256": "0b8801fead7b4a693ec6c4e13ec5ac1c0ed25b2872428fbf829b5c649c670494",
"fileName": "002-wordpress.org_news/0002-sunita-rai-featured-img.jpg",
"zipFile": "images.zip",
"zipUrl": "https://api.apify.com/v2/key-value-stores/<your-run-store>/records/images.zip?signature=…",
"via": "direct",
"downloadedAt": "2026-09-24T11:39:38.560Z"
}

The OUTPUT record has the ZIP link(s), totals and a line per page (images found, saved, duplicates, filtered, failed, and why a page failed). More: examples/three-pages-one-zip.json.

Input

FieldDefaultWhat it does
urlsrequiredPage URLs and/or direct image URLs, mixed. Bare domains get https://.
outputzipzip (one ZIP, a folder per page), zipPerPage, files (each image in the key-value store with its own link) or list (metadata only).
minWidth, minHeight0Skip smaller images (measured from the file). 100 skips icons and thumbnails.
formatsalle.g. ["jpeg", "png", "webp"] (real format from the bytes).
minFileSizeKb, maxFileSizeMb0, 25File size limits.
urlPattern, excludeUrlPattern–Regex on the image URL, e.g. /products/ or logo|icon|sprite.
sameDomainOnlyfalseSkip images hosted on other sites (ads, trackers); the site's own CDN subdomains count.
upgradeToOriginalstrueFull-size originals instead of CDN thumbnails (falls back to the page's copy).
srcsetlargestlargest, all sizes, or none.
includeLinkedImages, includeCssBackgrounds, includeMetaImagestrueWhere to look.
includeIcons, includeDataUrisfalseFavicons/touch icons; inline data: images.
preferOriginalFormattrueAsk CDNs for the original JPEG/PNG instead of WebP/AVIF copies.
dedupe, skipTrackingPixelstrueRemove duplicates; skip 1×1 pixels.
fileNamingoriginal0001-original-name.jpg, alt, index or hash.
zipPartSizeMb1000Split big ZIPs into parts.
maxImagesPerPage, maxImagesTotal500, 100000Safety caps.
proxyConfiguration, retryWithProxynone, trueBlocked requests (403/429/503) are retried once through Apify Proxy.
monitor, monitorKeyfalseOnly images that are new since the last monitor run.

Output

  • Dataset: one image row per delivered image (fields above). Pages that failed or had no images get a free page-error row with the reason (HTTP 403, "the page may build its content with JavaScript", …).
  • Key-value store: images.zip (or images-part-2.zip …, or one ZIP per page, or the individual files), and OUTPUT with the ZIP links and per-page counts. The dataset's zipUrl/fileUrl links work without a token.

Monitor mode: new images only

Tick monitor and schedule the run: Picpail remembers every image it has delivered for this URL list (by content hash) and returns only images that are new since the last monitor run, such as new products in a category, new photos in a gallery, or a changed homepage banner. Images you already have are skipped and not charged, so a daily check of a quiet page costs nothing. Use monitorKey to keep the history when you edit the URL list.

Pricing

  • $0.0005 per image delivered (event image-downloaded): downloaded, verified as a real image, measured and saved. 1,000 images = $0.50.
  • Very large files only: $0.0001 per started MB above 2 MB of one file (event large-image-megabyte), so a 5.5 MB photo costs $0.0009. Typical web images are well under 2 MB. Lower maxFileSizeMb or switch off upgradeToOriginals to avoid it.
  • Free: duplicates, images skipped by your filters, links that turn out to be HTML pages, failed downloads, failed pages, and in monitor mode images you already received.

Set a maximum charge per run in Apify and Picpail stops cleanly when it's reached.

Run it on a schedule

Apify Console → Schedules → Create new → cron 0 7 * * * (daily) → Add Actor → Picpail with your pages and "monitor": true. Through the API:

POST https://api.apify.com/v2/schedules?token=YOUR_TOKEN
{
"name": "picpail-new-product-photos",
"cronExpression": "0 7 * * *",
"timezone": "America/New_York",
"isEnabled": true,
"actions": [{
"type": "RUN_ACTOR",
"actorId": "cybermax/bulk-image-downloader",
"runInput": {
"body": "{\"urls\":[\"https://www.example-shop.com/collections/new\"],\"minWidth\":400,\"monitor\":true,\"monitorKey\":\"new-arrivals\"}",
"contentType": "application/json"
}
}]
}

Add an email, Slack or webhook notification on "Run succeeded" under the Actor's Integrations tab.

Integrations

API (synchronous): POST https://api.apify.com/v2/acts/cybermax~bulk-image-downloader/run-sync-get-dataset-items?token=YOUR_TOKEN with the input JSON returns the image rows (each with zipUrl or fileUrl). Use "output": "files" when each image needs its own link (e.g. to import into a CMS or a Google Sheet with =IMAGE()).

Make / Zapier: Apify app → "Run an Actor" (cybermax/bulk-image-downloader, run synchronously) → "Get dataset items" → map fileUrl, width, height, alt into Airtable, a CMS or cloud storage.

n8n: Apify node ("Run an Actor and get dataset"), or HTTP Request:

POST https://api.apify.com/v2/acts/cybermax~bulk-image-downloader/run-sync-get-dataset-items?token=YOUR_TOKEN
{"urls": ["https://books.toscrape.com/"], "output": "files", "minWidth": 100}

Google Sheets:

=IMPORTDATA("https://api.apify.com/v2/acts/cybermax~bulk-image-downloader/runs/last/dataset/items?format=csv&fields=pageUrl,imageUrl,width,height,alt,fileUrl&token=YOUR_TOKEN")

Python (pip install apify-client):

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("cybermax/bulk-image-downloader").call(run_input={"urls": ["https://books.toscrape.com/"], "minWidth": 100})
zip_url = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("OUTPUT")["value"]["zips"][0]["url"]
print(zip_url)

JavaScript (npm i apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('cybermax/bulk-image-downloader').call({ urls: ['https://books.toscrape.com/'], output: 'files' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

AI agents (MCP): Picpail is a tool on Apify's MCP server, https://mcp.apify.com/?tools=cybermax/bulk-image-downloader (Authorization: Bearer YOUR_TOKEN). Claude Desktop / Cursor config:

{ "mcpServers": { "picpail": { "url": "https://mcp.apify.com/?tools=cybermax/bulk-image-downloader",
"headers": { "Authorization": "Bearer YOUR_TOKEN" } } } }

Typical agent prompts: "Download every product photo from these 20 pages as a ZIP", "Which images on our blog have no alt text?", "Get the full-size images from this Shopify collection, at least 1000 px wide".

When NOT to use it

  • Pages that build their content with JavaScript (infinite-scroll feeds, single-page apps). Picpail reads the HTML the server sends; such pages come back with few images and a page-error row saying so. Use a browser-based scraper for those.
  • Sites behind strong bot walls (Cloudflare challenge, DataDome), e.g. Etsy and Unsplash search pages returned 403/401 in our tests, even through Apify's datacenter proxy. Try proxyConfiguration with residential proxies (billed by Apify to your account).
  • Pages behind a login, and whole-site crawls: Picpail downloads the pages you list; it doesn't follow links to other pages.
  • Images you have no right to reuse. Downloading is not a licence: product photos, stock photos and artwork belong to their owners. Use the files for analysis, backups of your own sites, or with permission.
  • Permanent hosting. ZIPs and files stay in the run's storage for your Apify plan's retention period (7 days on the free plan). Copy them somewhere permanent.

FAQ

Why is my ZIP bigger than the page? Full-size originals are much larger than the thumbnails a page shows (a Shopify product photo is often 2000–4000 px). Switch off upgradeToOriginals to get the page's own copies.

Why is a .jpg link a WebP file? It won't be by default: preferOriginalFormat asks CDNs for the original format, and each file's extension always matches its real format (format field).

How big can a job be? Images are written to disk one by one and ZIPs are split into parts, so memory stays flat (a 295 MB, 155-image test run peaked under 600 MB). For very large jobs raise the run's memory (disk grows with it) or use zipPerPage.

Also from CyberMax

  • Printwren: save the same pages as PDFs.
  • SnapScout: a screenshot and the text of each page.
  • Logolark: the company logo and icon for each domain.
  • Inkpluck: the article text of blog and news pages.

All tools: Boardroom Buys · DomainDNA · HireHeat · Swellmeter · Hollerdex · Gripeline · Keyfern

Changelog

  • 2026-09-24: First release: ZIP/files/list output, full-size originals for 9 CDN families, lazy-load and CSS images, real format/size per file, content dedupe, filters, monitor mode.

© 2026 CyberMax. All rights reserved.