Crawl an entire website and extract every image, video and audio asset into a clean, structured dataset — complete with alt text, declared dimensions, the exact source page, file type and where each asset was referenced. The Website Image & Media Extractor walks a site's internal links and pulls media from every page it visits, so you get a full media inventory instead of scraping one URL at a time. Point it at a domain and export thousands of rows to JSON, CSV or Excel.
Unlike a naive <img> grabber, this bulk image scraper catches media that hides from simple parsers: lazy-loaded images, responsive srcset candidates, <picture> sources, Open Graph / Twitter card images (og:image, twitter:image), favicons, <video> sources and posters, <audio> tracks, and images referenced in inline CSS background URLs. There's no API key to manage, no headless browser to babysit and no login — it reads the server HTML and returns each asset as its own row, with rich per-image metadata attached. That makes it ideal for building AI training datasets, running image SEO / alt-text audits, compiling asset inventories ahead of a migration, and generating clean bulk image download lists.
One row per media asset, with fields grouped by purpose:
Asset URL, type & source
mediaUrl— the absolute URL of the image, video or audio filemediaType—image,icon,videooraudiofoundIn— where the asset was referenced:img,srcset,meta,css-background,video,audio, and morefileExtension— lowercase file extension parsed from the media URL (e.g.jpg,png,webp,svg,mp4,mp3), ornullpageUrl— the page the asset was found on
Image metadata (images only)
alt— the imagealtattribute (ornullwhen missing — great for alt-text audits)title— the imagetitleattributewidth— declared width in pixelsheight— declared height in pixelsloading— the imageloadingattribute, e.g.lazyoreager
Video metadata
poster— the poster image URL declared on a<video>, if present
Timing
crawledAt— ISO 8601 timestamp of when the asset was captured
The default "Media" dataset view surfaces the columns you'll reach for most: pageUrl, mediaUrl, mediaType, fileExtension, alt, width, height.
- AI / ML training datasets. Pair every image
mediaUrlwith itsaltcaption to bootstrap image–text datasets for multimodal and image-captioning models — a ready-made source of image + alt-text caption pairs across a whole domain. - Image SEO & alt-text audits. Extract images site-wide and filter rows where
altis empty ornullto find every image missing alt text at scale, then hand the list to your content team. - Asset inventories & migrations. List every media file on a site before a redesign or replatform so nothing gets lost — a complete inventory of images, video and audio with their source pages.
- E-commerce & competitor research. Capture product imagery across an entire catalog — dimensions, formats and where each image lives — for competitive analysis or catalog QA.
- Bulk image download lists. Produce a clean, de-duplicated
mediaUrllist you can feed straight into a downloader to fetch the files in bulk. - Media compliance & licensing. Inventory all assets served on a domain — including favicons, social-share images and background images — for rights, licensing and compliance reviews.
- Open the Website Image & Media Extractor in Apify Console.
- Click Try for free.
- Leave the input empty to crawl a built-in demo site and see the output shape, or paste one or more URLs into Start URLs.
- (Optional) Set Crawl scope, Max pages to crawl and the include toggles, then click Start.
- When the run finishes, open the Dataset tab and Export to JSON, CSV or Excel.
# Install and log in
npm i -g apify-cli
apify login
# Run with defaults (empty input crawls a demo site)
apify call logiover/website-image-media-extractorRun against your own site with a custom scope and selective extraction:
apify call logiover/website-image-media-extractor --input '{
"startUrls": [{ "url": "https://example.com" }],
"crawlScope": "same-domain",
"maxPagesToCrawl": 500,
"includeImages": true,
"includeVideo": true,
"includeAudio": false,
"includeBackgroundImages": true,
"dedupeAcrossPages": true
}'Run the actor and get dataset items back in a single request:
curl -X POST \
"https://api.apify.com/v2/acts/logiover~website-image-media-extractor/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"startUrls": [{ "url": "https://example.com" }],
"maxPagesToCrawl": 200,
"includeImages": true
}'JavaScript (npm install apify-client):
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('logiover/website-image-media-extractor').call({
startUrls: [{ url: 'https://example.com' }],
crawlScope: 'same-domain',
maxPagesToCrawl: 500,
includeImages: true,
includeVideo: true,
includeAudio: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Extracted ${items.length} media assets`);
console.log(items[0]);Python (pip install apify-client):
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("logiover/website-image-media-extractor").call(run_input={
"startUrls": [{"url": "https://example.com"}],
"crawlScope": "same-domain",
"maxPagesToCrawl": 500,
"includeImages": True,
"includeVideo": True,
"includeAudio": True,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["mediaType"], item["mediaUrl"], item.get("alt"))All fields are optional. An empty input crawls a default demo site so you can preview the output shape immediately.
| Field | Type | Default | Description |
|---|---|---|---|
startUrls |
array of { url } |
demo site | Websites to crawl. The actor follows internal links and extracts media from every page. Empty = default demo site. |
crawlScope |
string (dropdown) | same-domain |
How far to follow links. Same domain only (same-domain), Include subdomains (include-subdomains), or Single page only (no crawl) (single-page). |
maxPagesToCrawl |
integer | 1000 |
Maximum pages to visit per run. 0 = no limit / whole site. Min 0. |
includeImages |
boolean | true |
Extract <img>, srcset, <picture>, og:image / twitter:image and favicons. |
includeVideo |
boolean | true |
Extract <video> sources and posters. |
includeAudio |
boolean | true |
Extract <audio> sources. |
includeBackgroundImages |
boolean | true |
Extract images referenced in inline CSS background URLs. |
dedupeAcrossPages |
boolean | true |
Output each asset once for the whole crawl (clean inventory). Turn off to log every occurrence with its source page. |
maxConcurrency |
integer | 10 |
Parallel requests. Lower this if the target site rate-limits. Min 1. |
proxyConfiguration |
object | { "useApifyProxy": true } |
Apify proxy settings. |
Notes
crawlScopeis a dropdown with three options — pick Same domain only for a typical site, Include subdomains to also traverseblog.,shop., etc., or Single page only (no crawl) to extract media from just the start URL(s) without following links.maxPagesToCrawlset to0removes the cap and crawls the whole site.- The include toggles (
includeImages,includeVideo,includeAudio,includeBackgroundImages) let you extract selectively — e.g. images only, or skip CSS background images for a leaner dataset.
Each dataset row is a single media asset.
| Field | Type | Description |
|---|---|---|
pageUrl |
string | Page the asset was found on |
mediaUrl |
string | Absolute URL of the media asset |
mediaType |
string | image, icon, video or audio |
foundIn |
string | Where the asset was referenced (img, srcset, meta, css-background, video, audio, …) |
fileExtension |
string | null | Lowercase file extension of the media URL |
crawledAt |
string | ISO 8601 timestamp |
alt |
string | null | Image alt attribute (images only) |
title |
string | null | Image title attribute (images only) |
width |
integer | null | Declared width in px (images only) |
height |
integer | null | Declared height in px (images only) |
loading |
string | null | Image loading attribute, e.g. lazy / eager (images only) |
poster |
string | null | Poster image URL for a video, if present |
Sample item (an image row):
{
"pageUrl": "https://example.com/products/blue-widget",
"mediaUrl": "https://cdn.example.com/img/blue-widget-800.jpg",
"mediaType": "image",
"foundIn": "img",
"fileExtension": "jpg",
"crawledAt": "2026-07-13T09:41:07.512Z",
"alt": "Blue widget on a white background",
"title": "Blue Widget",
"width": 800,
"height": 600,
"loading": "lazy",
"poster": null
}A video row looks similar but carries mediaType: "video", foundIn: "video", and a poster URL when the <video> declares one; image-only metadata (alt, width, height, loading) is null for non-image assets.
- Schedules. Run the extractor on a cron schedule (daily, weekly) to keep a fresh media inventory of a site as it changes.
- Webhooks. Fire an Apify webhook on run completion to notify your system, kick off a downstream job, or push the dataset somewhere.
- Google Sheets / Amazon S3. Export the dataset straight to Google Sheets for the content team, or drop CSV/JSON into an S3 bucket for your pipeline.
- Zapier · Make · n8n · Pipedream. Trigger the actor and route results through the Apify integrations on any of these platforms — no code required.
- Pipe into a bulk downloader. Feed the
mediaUrlcolumn into a bulk image downloader (see Related actors) to fetch the actual files after you've built your inventory.
Every run's dataset can be downloaded or served as:
- CSV
- JSON
- JSONL
- Excel (XLSX)
- XML
Export from the Console Dataset tab, the CLI, or the Apify API.
Enter the site's URL in Start URLs, leave Crawl scope on Same domain only, and set Max pages to crawl to 0 for the whole site. The actor follows internal links and returns one row per image with its mediaUrl, source pageUrl, alt, dimensions and file type. Export to CSV or JSON when it finishes.
No — it returns URLs and metadata, not the binary files. Each row gives you the absolute mediaUrl, mediaType, fileExtension and (for images) alt, width, height and loading. To download the actual files, pipe the mediaUrl list into a bulk image downloader (see Related actors).
Yes. It extracts responsive srcset candidates, <picture> sources and images with loading="lazy" from the HTML, and reports the loading attribute on each image row — so lazy-loaded images that a simple <img> grabber would miss still appear in your dataset.
Yes — this is a common use case. Crawl a domain, keep includeImages on, and pair each image mediaUrl with its alt text to create image + caption pairs for training or fine-tuning multimodal / image-captioning models. Export to JSONL for easy ingestion.
Run the extractor across your site, then filter the dataset for rows where alt is empty or null. Those are the images missing alt text. The pageUrl on each row tells your team exactly which page to fix.
No — it reads the server-rendered HTML for speed and low cost. It still catches srcset, <picture>, og:image / twitter:image, favicons, <video> posters, <audio> sources and inline CSS background images. Media injected purely by client-side JavaScript after load isn't parsed.
Set Max pages to crawl to 0 (no limit) and use Same domain only — or Include subdomains to also traverse blog., shop. and similar. Keep dedupeAcrossPages on for a clean, one-row-per-asset inventory across the entire crawl.
After a run, open the Dataset tab in Apify Console and click Export (CSV, JSON, JSONL, Excel or XML). You can also fetch items via the API's run-sync-get-dataset-items endpoint or the apify-client libraries — see Quick start.
There's no third-party API key to obtain — the actor runs on the Apify platform and needs only your Apify token to call it programmatically. Start on Apify's free tier and pay per result as you scale.
You are responsible for how you use the actor. Crawl sites you own or have permission to crawl, respect each site's Terms of Service and robots.txt, and confirm you hold the rights before reusing any downloaded media. For licensing reviews, the inventory this actor produces is a helpful starting point — but it is not legal advice.
| Actor | What it does |
|---|---|
| Bulk Image Downloader | Download image files in bulk from a list of URLs — the natural next step after building a mediaUrl list. |
| Website SEO Audit Crawler | Crawl a site for on-page SEO issues, including image alt-text coverage. |
| Website Link Graph Crawler | Map a site's internal link structure across every page. |
📄 Documentation only — the Actor runs on the Apify platform.
MIT © 2026 logiover