Bulk File Downloader and Website Image Extractor avatar

Bulk File Downloader and Website Image Extractor

Pricing

Pay per event

Go to Apify Store
Bulk File Downloader and Website Image Extractor

Bulk File Downloader and Website Image Extractor

Bulk file downloader: PDFs, images, any file from a URL list, CSV or dataset, with retries, filename template and ZIP. $0.001 per file, failed files free. Also extracts images from pages.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Penny Data

Penny Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 hours ago

Last modified

Categories

Share

Website Image Extractor: All Images from Any Page

Two modes. Bulk file downloader: $0.001 per file downloaded. Image extractor: $0.002 per image row delivered (about $2 per 1,000 images). You are charged only for result rows that contain an image; pages that fail, are blocked by robots.txt or contain no images cost nothing; failed downloads are never charged.

Give it public page URLs. It reads the HTML and returns one row per unique image: <img src> and srcset (largest candidate), <picture><source>, og:image / twitter:image, and optionally CSS background-image: url(). Plain HTTP, no browser, no proxies, no login.

Bulk file downloader (mode files)

$0.001 per file successfully downloaded. Failed, timed-out, oversized and 4xx/5xx files are retried (timeouts, network errors, 429, 5xx; default 2 retries with backoff) and are never charged. Any file type: PDF, images, CSV, ZIP, video, audio.

Input example:

{
"mode": "files",
"fileUrls": [{ "url": "https://example.com/a.pdf" }, { "url": "https://example.com/photo.jpg" }],
"filenameTemplate": "{index}-{basename}",
"createZip": true,
"maxCostUsd": 5
}
  • URL sources (combined, deduplicated): fileUrls (plain list), csvUrl (+ csvColumn header or 0-based index; a Google Sheet CSV export link works), datasetId (+ datasetField).
  • filenameTemplate: {index}, {basename}, {name}, {ext}, {host}. Default {index}-{basename}.
  • createZip: also writes all files to one files.zip record in the key-value store (up to 400 MB; larger sets stay available as individual records).
  • maxCostUsd: hard guard, at most floor(maxCostUsd / 0.001) files are downloaded. Also maxFiles, maxFileMb (default 50), retries, timeoutSecs, concurrency.
  • Output: one dataset row per URL (status ok/error, error, fileName, kvsKey, kvsUrl, contentType, bytes, attempts).
  • Only public http(s) URLs are fetched; private and internal addresses are blocked. You are responsible for the right to download and store the files.

Image extraction mode (default, mode images)

Compared with per-URL pricing

This actoronescales/bulk-image-downloader (as listed 2026-10)
Price$0.002 per image found$0.07 per URL processed
Page with 5 images$0.010$0.07
Page with 20 images$0.040$0.07
Page with 0 images$0$0.07
Break-evenabout 35 images per page

Pages with more than ~35 images cost more here than at a flat $0.07 per URL; use maxImages or minWidth to control spend. Prices of other actors may change; check their listing.

Input

  • startUrls: page URLs (prefilled with a Wikipedia article). Aliases inputUrls, urls, url are merged in.
  • cssSelector: only return images inside matching elements (e.g. .product-gallery). Each row also has a filename.
  • maxPagesPerStart (default 1): also follow same-site links, up to N pages per start URL.
  • minWidth, minBytes: drop small images (unknown width/size is kept).
  • includeCssBackgrounds (default off), sameDomainOnly (default off), fetchMetadata (default on: HEAD per image for type and size).
  • downloadToKvs (default off): store each image (max 10 MB) in the key-value store; failed downloads are not delivered or charged.
  • maxImages (default 100), respectRobotsTxt (default on), timeoutSecs.

Output (one row per image)

pageUrl, imageUrl, alt, width, height, contentType, bytes, source (img, img-srcset, picture-source, og:image, twitter:image, css-background), plus kvsKey/kvsUrl when downloading. Width/height are only what the page declares; the actor does not decode images.

Limits

  • Lazy-loaded images are found when their URL is in the HTML (data-src, data-lazy-src, data-original, data-srcset, <picture>, <noscript>, data-bg). Images added by JavaScript after page load are not seen (no rendering).
  • A page with no images produces one row with status: no_images and a reason (JavaScript-rendered gallery, selector matched nothing, non-HTML). These rows are never charged.
  • dedupeAcrossPages (default on) delivers and charges each image URL once per run. External stylesheets are not read.
  • Only the pages you supply (and, if enabled, same-site links) are fetched. No search-engine scraping. Private and internal addresses are blocked. You are responsible for respecting the copyright and license of the images you download.
  • Not affiliated with any website you scan.

Next step: upscale the images

Each row of this Actor's output has an imageUrl. To make them larger, feed the imageUrl values into Image Upscaler (OpenCV, fast and cheap), which returns each image 2x, 3x or 4x larger. It is a separate Actor with its own pay-per-event price; you are charged for it only when you run it.

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
// 1. Run this Actor, then read its dataset.
const run = await client.actor('pennydata/website-image-extractor').call({ /* your input */ });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
// 2. Send the image URLs to the upscaler.
const imageUrls = items.map((i) => i.imageUrl).filter(Boolean).slice(0, 500);
const up = await client.actor('pennydata/image-upscaler-fast').call({ imageUrls, scale: '2', outputFormat: 'png' });
const out = await client.dataset(up.defaultDatasetId).listItems();
console.log(out.items.map((r) => r.outputUrl));

The upscaler accepts up to 500 URLs per run and images up to 2 megapixels and 25 MB; larger images come back as an error row and are not charged. It uses small OpenCV networks, not generative AI, so expect cleaner edges at a larger size rather than new detail. Use minWidth here to skip tiny icons before upscaling.

Free bookmarklet: list images on any page

Need the image URLs of just one page you are looking at? Use this free bookmarklet instead of the Actor. It runs only in your browser, makes no network calls and sends nothing anywhere. Create a new browser bookmark and paste the line below as its URL, open any page, click the bookmark, then press Copy.

javascript:(function%20()%20{var%20seen%20=%20{},%20urls%20=%20[];function%20add(u)%20{if%20(!u)%20return;try%20{%20u%20=%20new%20URL(u,%20document.baseURI).href;%20}%20catch%20(e)%20{%20return;%20}if%20(/%5E(https?:|data:image)/.test(u)%20&&%20!seen[u])%20{%20seen[u]%20=%201;%20urls.push(u);%20}}function%20srcset(s)%20{%20(s%20||%20'').split(',').forEach(function%20(p)%20{%20add(p.trim().split(/%5Cs+/)[0]);%20});%20}function%20bg(v)%20{%20var%20re%20=%20/url%5C((['"]?)(.*?)%5C1%5C)/g,%20m;%20while%20((m%20=%20re.exec(v%20||%20'')))%20add(m[2]);%20}document.querySelectorAll('img').forEach(function%20(i)%20{%20add(i.currentSrc%20||%20i.src);%20add(i.getAttribute('data-src'));%20srcset(i.srcset);%20});document.querySelectorAll('source[srcset]').forEach(function%20(s)%20{%20srcset(s.srcset);%20});document.querySelectorAll('meta[property="og:image"],meta[name="twitter:image"]').forEach(function%20(m)%20{%20add(m.content);%20});document.querySelectorAll('link[rel~="icon"],link[rel="apple-touch-icon"]').forEach(function%20(l)%20{%20add(l.href);%20});document.querySelectorAll('*').forEach(function%20(e)%20{%20bg(getComputedStyle(e).backgroundImage);%20});var%20old%20=%20document.getElementById('wie-box');%20if%20(old)%20old.remove();var%20d%20=%20document.createElement('div');%20d.id%20=%20'wie-box';d.style.cssText%20=%20'position:fixed;z-index:2147483647;top:10px;right:10px;width:460px;max-width:95vw;background:%23fff;color:%23000;border:2px%20solid%20%23333;padding:10px;font:13px%20sans-serif;box-shadow:0%204px%2020px%20%230006';var%20h%20=%20document.createElement('div');%20h.textContent%20=%20urls.length%20+%20'%20image%20URLs%20found';%20h.style.fontWeight%20=%20'bold';var%20t%20=%20document.createElement('textarea');%20t.id%20=%20'wie-text';%20t.value%20=%20urls.join('%5Cn');%20t.style.cssText%20=%20'width:100%25;height:240px;margin:6px%200;box-sizing:border-box';var%20b%20=%20document.createElement('button');%20b.textContent%20=%20'Copy';%20b.onclick%20=%20function%20()%20{%20t.select();%20document.execCommand('copy');%20};var%20c%20=%20document.createElement('button');%20c.textContent%20=%20'Close';%20c.onclick%20=%20function%20()%20{%20d.remove();%20};var%20a%20=%20document.createElement('a');%20a.href%20=%20'https://apify.com/pennydata/website-image-extractor';%20a.target%20=%20'_blank';%20a.rel%20=%20'noopener';a.textContent%20=%20'Need%20many%20pages%20or%20bulk%20download?%20Website%20Image%20Extractor';%20a.style.cssText%20=%20'display:block;margin-top:8px;color:%2306c';d.append(h,%20t,%20b,%20c,%20a);%20document.body.appendChild(d);})();

It lists img src/srcset, source sets, lazy-load data-src, CSS backgrounds, og:image and icons, with duplicates removed. It only sees the page you are on. For many pages, whole sites, a CSS selector filter or downloading the files, run this Actor.

AI disclosure

Built with AI assistance (Claude); maintained by the publisher.

Other Actors from the same publisher for website work. Each is a separate Actor with its own pay-per-event price; you are charged only for what you run.