Free tool
Image URL extractor
Paste HTML, Markdown, CSS, JSON or plain text and pull out every image URL — including lazy-loaded, srcset and CSS background images. Preview them, then export as TXT, CSV or JSON.
Formats
HTML, Markdown, code or text input
0 image URLs
0 images · 0 domains · deduplicatedRuns entirely in your browser — nothing is uploaded.
Code examples
Do the same thing in your own pipeline
The tool above parses in the browser. Here is the equivalent image extraction with the standard HTML parser in each language.
# pip install beautifulsoup4
import re
from urllib.parse import urljoin
from bs4 import BeautifulSoup
IMAGE_EXT = re.compile(r"\.(jpe?g|png|gif|webp|avif|svg|bmp|ico|tiff?)($|\?)", re.I)
def extract_image_urls(html: str, base: str) -> list[str]:
soup = BeautifulSoup(html, "html.parser")
found: list[str] = []
for img in soup.find_all("img"):
for attr in ("src", "data-src", "data-original", "data-lazy-src"):
if img.get(attr):
found.append(img[attr])
for srcset in (img.get("srcset"), img.get("data-srcset")):
if srcset:
found += [part.strip().split(" ")[0] for part in srcset.split(",") if part.strip()]
for source in soup.select("picture source[srcset]"):
found += [part.strip().split(" ")[0] for part in source["srcset"].split(",") if part.strip()]
for meta in soup.select('meta[property*="image"], meta[name*="image"]'):
if meta.get("content"):
found.append(meta["content"])
for el in soup.select("[style]"):
found += re.findall(r"url\(\s*['\"]?([^'\")]+)", el["style"])
seen, out = set(), []
for value in found:
url = urljoin(base, value.strip())
if not url.startswith("http") or not IMAGE_EXT.search(url):
continue
if url not in seen:
seen.add(url)
out.append(url)
return out
html = '<img src="/assets/hero.png" alt="Hero"><img data-src="https://cdn.example.com/a.webp">'
for url in extract_image_urls(html, "https://example.com/"):
print(url)How it works
Where image URLs actually hide
- img src plus the lazy-loading attributes real sites use — data-src, data-original, data-lazy-src.
- Every candidate inside srcset, data-srcset and picture sources, with its width or density descriptor kept.
- CSS backgrounds: url() values in style attributes and inline style blocks.
- Social and structured data: Open Graph and Twitter image tags, favicons, apple-touch icons and image fields in JSON-LD.
- Anything else: quoted image paths in JSON, JS or CSS, Markdown image syntax and bare URLs in plain text.
- Relative paths resolved against your base URL, deduplicated, filtered by format and domain, then exported.
With Irmu
When you also need to fetch the page
Most product galleries only appear after JavaScript runs. Irmu renders the page and returns the final HTML — extract the images from that.
crawl_to_images.py
# pip install requests beautifulsoup4
import csv, os, requests
from urllib.parse import urljoin
from bs4 import BeautifulSoup
target = "https://example.com/products/widget"
# Irmu fetches the page: rendering, proxies, retries and anti-bot handling included.
resp = requests.get(
"https://app.irmu.com/api/crawl",
headers={"Authorization": f"Bearer {os.environ['IRMU_API_KEY']}"},
params={"url": target, "js": "true", "premium": "true", "wait_until": "networkidle2"},
timeout=90,
)
resp.raise_for_status()
soup = BeautifulSoup(resp.text, "html.parser")
images = []
for img in soup.find_all("img"):
src = img.get("src") or img.get("data-src")
if src:
images.append({"url": urljoin(target, src), "alt": img.get("alt", "")})
with open("images.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["url", "alt"])
writer.writeheader()
writer.writerows(images)
print(f"{len(images)} images from {target}")download_images.mjs
// Node 18+ — download every image URL you extracted
import { writeFile, mkdir } from "node:fs/promises";
import { basename } from "node:path";
const urls = JSON.parse(await (await import("node:fs/promises")).readFile("image-urls.json", "utf8"))
.map((row) => row.url);
await mkdir("images", { recursive: true });
for (const url of urls) {
const res = await fetch(url, { headers: { "User-Agent": "Mozilla/5.0" } });
if (!res.ok) {
console.warn("skip", url, res.status);
continue;
}
const buffer = Buffer.from(await res.arrayBuffer());
await writeFile(`images/${basename(new URL(url).pathname) || "image"}`, buffer);
}FAQ
Questions about this tool
Turn any URL into clean image data
Fetch, render and extract with one API. 200 free credits every month, no card required.