Bulk Image Downloader - Download All Images from URLs + ZIP
Pricing
from $0.80 / 1,000 files
Bulk Image Downloader - Download All Images from URLs + ZIP
Download all images (JPG, PNG, WebP, SVG, GIF, AVIF) or files like PDFs from web pages or direct links into a ZIP and key-value store. Input: URLs; optional file types, minimum size, crawl depth. Returns per file: download URL, type, width, height, bytes, alt text, source page. Default: 20 files.
Pricing
from $0.80 / 1,000 files
Rating
0.0
(0)
Developer
Bence Kadi
Maintained by CommunityActor stats
0
Bookmarked
5
Total users
3
Monthly active users
19 days ago
Last modified
Categories
Share
Bulk Image Downloader: download all images from URLs + ZIP
Download all images from any list of web pages, or a list of direct image/file links, into one ZIP file and the run's key-value store. Every file gets a public link and a dataset row with its size, width × height, type, alt text and SHA-256. You pay $0.80 per 1,000 files saved, and failures are free.
🖼️ What is Bulk Image Downloader?
It reads the HTML of your pages (no browser, so it is fast and cheap), finds every image or file, checks its real type from its bytes and saves it. It also handles PDFs, Word/Excel/PowerPoint, CSV, ZIP, MP3, MP4 and more.
- Finds the images other tools miss: the largest
srcset/<picture>version, lazy-loaded images (data-src,data-srcset,data-lazy-src,data-originaland 9 more),<noscript>,og:image, CSS backgrounds, video posters, JSON-LD images and file links. Placeholders and 1x1 tracking pixels are ignored. - Real file checks: an "image" that is really an HTML error or hotlink-protection page is caught and not charged. Width and height are read for JPG, PNG, WebP, GIF, AVIF, SVG, BMP, ICO, TIFF and HEIC.
- Filters and dedupe: type, min width/height, min/max size; identical content (SHA-256) is skipped for free.
Use cases: Developer tools (process & convert media, transform & process data) · Collect & distribute content.
Use cases
- E-commerce teams: download supplier or shop product photos for migration or marketplace listings.
- AI and RAG pipelines: collect openly licensed images with alt text, dimensions and SHA-256.
- Agencies: back up every image and PDF of an old site before a redesign.
- Research and archiving: save the reports (PDF) and documents linked from public pages.
- URL list to ZIP: paste thousands of direct links from a spreadsheet and get one archive back.
- Developers: call it from Make, Zapier, n8n, the API or an AI agent (MCP) and use each file's
publicUrl.
Output fields
One dataset row per file. All fields:
| Field | Description | Example |
|---|---|---|
sourcePage | Page where the file was found. null for direct links from your input | https://commons.wikimedia.org/wiki/Category:Quality_images_of_cats |
fileUrl | Original URL of the file | https://upload.wikimedia.org/.../Chartreux-cat-edouard-marie.jpg |
discoveredBy | Where it was found: input, img, srcset, picture, lazy, noscript, meta, css, media, jsonld, link (or page for a failed page row) | srcset |
altText | The image's alt text, when the page has one | null |
status | stored, failed, blocked, and for skipped rows filtered or duplicate | stored |
storedKey | Key of the file in the key-value store (also its name inside the ZIP) | 00005-Chartreux-cat-edouard-marie.jpg |
publicUrl | Public download link of the file | https://api.apify.com/v2/key-value-stores/<store-id>/records/... |
zipKey | Which ZIP part contains the file | files.zip |
fileType | Real type, detected from the file's bytes | jpg |
contentType | MIME type | image/jpeg |
bytes | File size in bytes | 1760428 |
width | Image width in pixels (null if not an image or unreadable) | 2400 |
height | Image height in pixels | 1714 |
sha256 | SHA-256 checksum of the file content | 793c03f7cb71... |
duplicateOf | For skipped duplicates: URL of the first copy | null |
httpStatus | HTTP status of the download | 200 |
error | Why the file failed or was skipped (null when stored) | HTTP 404 |
downloadedAt | When the file was saved (UTC) | 2026-10-05T07:02:16.349Z |
🚀 How to use Bulk Image Downloader
- Open Bulk Image Downloader in Apify Store and click Try for free (or Start).
- Paste your URLs, one per line: web pages (
https://example.com/gallery) and/or direct file links (https://example.com/photo.jpg,.../report.pdf). - Pick the file types (default: JPG, PNG, WebP, GIF, SVG, AVIF). Optionally set min width (e.g. 150 px skips icons) and max files.
- Click Start. The prefilled example (30 freely licensed images from 2 Wikimedia Commons pages) takes about 15 seconds.
- Download your results: the ZIP archive link in the Output tab downloads everything at once. The Files tab shows previews and links, and you can export the table as JSON, CSV, Excel and more.
🔧 Input guide
URLs (urls)
Web pages and/or direct file links, one per line (example.com works too). Up to 5,000 per run; unusable lines are skipped and listed in invalidInputs in the run summary.
- Good: a gallery page with images in its HTML (
https://commons.wikimedia.org/wiki/Category:Quality_images_of_cats), or a direct link (https://example.com/report.pdf). - Bad: a gallery built by JavaScript (infinite scroll, some single-page apps): those images are not in the HTML. Collect their URLs another way and paste them as direct links.
- Direct file links are always downloaded, whatever their type. Private and local addresses (localhost, 192.168.x, cloud metadata) are refused.
File types (fileTypes)
Which files found on pages to keep: jpg, png, webp, gif, svg, avif, bmp, ico, tiff, heic, pdf, doc(x), xls(x), ppt(x), odt, ods, rtf, epub, csv, txt, json, xml, zip, gz, 7z, rar, mp3, wav, ogg, m4a, mp4, webm, mov. A file whose real type (from its bytes) is not selected is skipped for free. Tip: for all PDFs of a website, select only pdf with crawl depth 1.
Limits and filters
maxFiles(default 100, max 100,000): stop after this many saved files. Also a hard cap on the cost.minWidth/minHeight(px): 150 skips icons, spacers and tracking pixels. Images whose size can't be read are kept.minFileSizeKb/maxFileSizeMb(default 0 / 25, max 100 MB): the max is checked before downloading when the server reports the size, and again while streaming.maxDepth:0(default) = only your pages,1= also pages they link to on the same website,2= one level further. Direct file links are never crawled.maxPagesPerStartUrl(default 20, max 500): page cap per listed URL when crawling. Warning: depth 2 on a big site reaches many pages.
ZIP, storage and names
createZip(on) packs every file intofiles.zip.storeFiles(on) also saves each file with a public link; turn it off if you only need the ZIP. At least one must be on.zipMaxMb(default 100, range 10-400): start a new ZIP part at this size. Parts need about 2x their size in memory.dedupe(on): skip identical content (SHA-256), even under another URL. Free.fileNamePattern(default{index}-{name}): tokens{index},{name},{host},{hash},{page},{type}; must contain{index},{name}or{hash}. The extension is added. Characters not allowed in keys (including non-ASCII) become-.
Other options
outputSkipped(off): add free rows for skipped files (duplicates, filtered, robots.txt). Failed downloads are always listed.maxConcurrency(default 10, max 50): at most 6 per website, and fewer on small memory.proxyConfiguration: optional Apify Proxy (datacenter). Residential proxies are refused.
Always on: robots.txt (including Crawl-delay, capped at 30 s). Requests time out after 30 s, one download after 5 minutes, and 408/425/429/5xx errors are retried up to 2 times.
Example input
{"urls": ["https://commons.wikimedia.org/wiki/Category:Quality_images_of_cats","https://commons.wikimedia.org/wiki/Category:Featured_pictures_of_landscapes"],"fileTypes": ["jpg", "png", "webp", "gif", "svg", "avif"],"maxFiles": 30,"minWidth": 150,"maxDepth": 0,"createZip": true,"storeFiles": true,"dedupe": true,"fileNamePattern": "{index}-{name}"}
📦 Output
Dataset row (real run on 2026-10-05)
This row is a direct link to a full-size Wikimedia Commons photo; the store ID in publicUrl is shortened:
{"sourcePage": null,"fileUrl": "https://upload.wikimedia.org/wikipedia/commons/8/80/Chartreux-cat-edouard-marie.jpg","discoveredBy": "input","altText": null,"status": "stored","storedKey": "00005-Chartreux-cat-edouard-marie.jpg","publicUrl": "https://api.apify.com/v2/key-value-stores/<store-id>/records/00005-Chartreux-cat-edouard-marie.jpg","zipKey": "files.zip","fileType": "jpg","contentType": "image/jpeg","bytes": 1760428,"width": 2400,"height": 1714,"sha256": "793c03f7cb71c5b3aa1bde84141fed124b2e3021dfc95998e07d2be4f7dc9281","duplicateOf": null,"httpStatus": 200,"error": null,"downloadedAt": "2026-10-05T07:02:16.349Z"}
Failed files get status: "failed" or "blocked" and an error such as HTTP 404, Got a web page instead of a file (blocked hotlink or removed file?) or Domain not found (DNS lookup failed). They are not charged.
Dataset views
- Files (default): image preview, original URL, type, dimensions, bytes, alt text, source page, status, error.
- Links and checksums: store key, file link, ZIP part, MIME type, SHA-256, duplicate of, HTTP status, download time.
Key-value store files
- Each file under its
storedKey, with a public link (whenstoreFilesis on). files.zip: all saved files, named like their keys. It is written to disk as files arrive; atzipMaxMbit is uploaded andfiles-part-2.zip,files-part-3.zip... follow. Already-compressed formats (JPG, PNG, MP4...) are stored as-is.RUN_SUMMARY: JSON report with pages scanned, files saved, MB, skipped and failed counts and the ZIP links. Real example (shortened):
{"pagesScanned": 2,"filesFound": 228,"filesStored": 30,"filesFailed": 0,"skipped": { "dimensions": 5, "robotsTxt": 1 },"zipFiles": [{ "key": "files.zip", "files": 30, "bytes": 435399, "mb": 0.44 }],"chargeLimitReached": false,"durationSecs": 5.7}
The Output tab links to both views, the ZIP and the run summary.
Export
Export the dataset as JSON, CSV, Excel, XML, RSS or an HTML table from the Storage tab, or fetch it with the Apify API. The ZIP is at https://api.apify.com/v2/key-value-stores/<store-id>/records/files.zip.
💵 Pricing: $0.80 per 1,000 files
fileevent: $0.0008 per saved file ($0.80 per 1,000).large-file-mbevent: $0.0005 for each started MB above the first 2 MB of one file. A 5 MB photo = $0.0008 + 3 × $0.0005 = $0.0023. Typical web images are far below 2 MB and never pay it.- Plus Apify's $0.00005 per-run start fee.
- Free: pages scanned, failed downloads, 404s, blocked pages, duplicates, filtered-out files and robots.txt-skipped files.
| Run | Files saved (under 2 MB each) | Cost |
|---|---|---|
| Prefilled example | 30 | $0.024 + $0.00005 |
| Product photos | 1,000 | $0.80 + $0.00005 |
| Thumbnails | 10,000 | $8.00 + $0.00005 |
| Largest run allowed | 100,000 | $80.00 + $0.00005 |
Set Max charge per run in the run options to cap spending: the run stops cleanly at your limit and never keeps a file it didn't charge for.
Why per file? Tools that charge per input URL cost $7-70 per 1,000 URLs, so 1,000 direct image links cost 10-90× more there.
🔌 Use it via API
JavaScript (npm install apify-client):
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });const run = await client.actor('kadi_bence/bulk-image-downloader').call({urls: ['https://commons.wikimedia.org/wiki/Category:Quality_images_of_cats'],fileTypes: ['jpg', 'png', 'webp'],maxFiles: 50,minWidth: 150,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.map((i) => i.publicUrl));
Python (pip install apify-client):
from apify_client import ApifyClientclient = ApifyClient("YOUR_API_TOKEN")run = client.actor("kadi_bence/bulk-image-downloader").call(run_input={"urls": ["https://example.com/report.pdf", "https://example.com/photo.jpg"],"createZip": True,"storeFiles": False,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["fileUrl"], item["status"], item["zipKey"])
cURL (runs the Actor and returns the dataset rows):
curl -X POST "https://api.apify.com/v2/acts/kadi_bence~bulk-image-downloader/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \-H "Content-Type: application/json" \-d '{"urls": ["https://example.com/gallery"], "maxFiles": 20}'
Apify CLI:
$apify call kadi_bence/bulk-image-downloader --input '{"urls": ["https://example.com/gallery"], "fileTypes": ["pdf"], "maxDepth": 1}'
MCP for AI agents (Claude, Cursor, VS Code and other MCP clients):
{"mcpServers":{"apify":{"url":"https://mcp.apify.com/?actors=kadi_bence/bulk-image-downloader"}}}
🔗 Integrations & scheduling
- Apify Schedules (cron): back up a blog's images every Monday into a fresh ZIP.
- Webhooks: on "run succeeded", call your URL, then fetch
files.zipfrom the run's key-value store. - Zapier / Make / n8n: new sheet row with an image URL → run the Actor → write each
publicUrlback. - Google Sheets, Slack, email: export the Files table to a sheet, or post the ZIP link to Slack when a run finishes.
🧰 Related tools by the same developer
Content pipelines
- Document to Markdown: PDF/Word/PowerPoint/Excel/OCR to Markdown and RAG chunks; $2 / 1,000 documents.
Website due diligence
- Website Tech Stack Detector: CMS, ecommerce, analytics, frameworks from 7,600+ fingerprints; $1.50 / 1,000 websites.
- SEO Site Audit Crawler: broken links, redirects, titles/meta, canonical, hreflang on every page; $1.50 / 1,000 pages.
- Website Screenshot & PDF API: full-page/mobile PNG, JPEG, WebP and PDF captures; $2.50 / 1,000 screenshots.
- Bulk WHOIS & RDAP Domain Lookup: registrar, age, expiry, DNS/MX/SPF/DMARC; $1.50 / 1,000 domains.
❓ FAQ
How does it work? It loads each page's HTML (no browser), extracts image and file links, downloads the selected files, checks their real type and size, and saves them to the ZIP and key-value store.
Am I allowed to download these images? Who owns the copyright? Downloading a file does not give you any rights to it. Copyright stays with the owners of the images and files, and you are responsible for having the right to download, store and reuse them: your own sites, openly licensed content such as Wikimedia Commons, or content you have permission for. Check the licence before you reuse anything. This is not legal advice. The Actor only downloads URLs you give it (and, with crawling on, pages on the same website). It always respects robots.txt, never logs in, and does not bypass paywalls, CAPTCHAs or bot protection; those downloads fail cleanly and are free. It doesn't extract personal data: it saves the files you asked for (and their alt text) into your own Apify storage.
Why are some images on a page missing? Pages that load their gallery with JavaScript don't have the images in their HTML. Also check your file types and min width/height filters, and turn on List skipped files too to see what was skipped and why.
What does "Blocked by the site's robots.txt" mean? The website asks automated tools not to fetch that page or file. We always follow it, and the file is free.
Is it a full-size image or a thumbnail?
From each <img> it takes the largest version the page offers in srcset/<picture>. Sites that only link to the full-size image ("view original") are covered when that link points directly to an image file.
How fast is it?
Usually 5-10 files per second per website. Downloading from several sites at once is faster. In one test, 150 files (3.9 MB) took 18 seconds. Sites whose robots.txt sets a Crawl-delay (e.g. 4 seconds) are downloaded at that pace.
How big can files and runs be? Files up to 100 MB each (default 25), up to 100,000 files per run. ZIP parts default to 100 MB (max 400 MB) and need about 2x their size in memory.
What does a big job cost? Exactly the per-file price above; cap it with Max files and Max charge per run.
Do I need a proxy? Usually not. Apify Proxy (datacenter) is available. Residential proxies are not supported.
What if a run fails?
Failed files are free and show the reason in error. If something looks wrong, open an issue in the Issues tab with the run link. Changes are listed in the changelog below.
📝 Changelog
- 2026-10-05: Store page rewritten.
- 1.0 (2026-10-05): First release.
- Images and 36 file types from pages or direct links
- lazy-load/srcset/picture/CSS/og:image discovery and an optional same-site crawl
- type check from bytes, dimensions, SHA-256 dedupe
- ZIP with parts and per-file public links
- robots.txt always on, private-network (SSRF) protection, failed files not charged
🤝 Need a custom version?
I build custom scrapers, scheduled data feeds and integrations (CSV, Excel, Google Sheets, API, MCP for AI agents). Tell me the sites and fields you need:
- Email: bence.kadi@gmail.com
- Apify profile: https://apify.com/kadi_bence
Related Actors
More low-cost Actors by the same developer, built on official APIs and public data:
- Website Screenshot & PDF API — full-page screenshots and PDFs of any URL
- Document to Markdown — PDF, Word, PowerPoint and Excel to clean Markdown, with OCR
- SEO Site Audit — 0-100 SEO score per page, broken links and fix hints
- Apple App Store Scraper — top charts, app details, developers and reviews
- PageSpeed Insights Bulk Checker — Core Web Vitals and Lighthouse scores in bulk
- Website Tech Stack Detector — CMS, ecommerce, analytics and frameworks of any website
- Bulk WHOIS & RDAP Domain Lookup — registrar, dates and DNS for many domains
All my Actors: apify.com/kadi_bence