Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

To collect image URLs reliably, inspect both the original HTML and the page after JavaScript runs. Record each image or source element’s URL attributes—including srcset—rather than treating img.src as a complete inventory. If images appear only after scrolling, render the page and collect again as content loads. A URL inventory can reveal possible tracking pixels, but it cannot prove tracking intent by itself.

What “every image” can mean

A page may declare a fallback image in src, several responsive choices in srcset, and alternatives inside a picture element. The browser may select only one of those choices for a particular viewport and device. A complete candidate inventory should preserve the declarations and their origins; reproducing the browser’s choice is a different task.

There are two useful collection passes:

  • Initial HTML: what the server returned before page scripts ran.
  • Rendered DOM: what is present after scripts execute and, if needed, after scrolling or interaction.

Neither pass guarantees every image a site could possibly show. The results are limited to URLs and elements exposed by the page state you collected.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Collect image declarations from the initial HTML with Python

For a page whose image markup is in its initial response, fetch the HTML, inspect both img and source elements, and resolve relative URLs against the response URL. This example records each element’s attributes and keeps srcset intact as a declaration rather than splitting it naively on commas.

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin

page_url = "https://example.com/page"
response = requests.get(page_url, timeout=20)
response.raise_for_status()

soup = BeautifulSoup(response.text, "html.parser")
base = response.url

for element in soup.select("img, picture source"):
    attrs = dict(element.attrs)
    record = {
        "element": element.name,
        "page_url": base,
        "src": urljoin(base, attrs["src"]) if attrs.get("src") else None,
        "srcset": attrs.get("srcset"),
        "attributes": attrs,
    }
    print(record)

The srcset value is a list of possible image candidates with optional width (w) or pixel-density (x) descriptors. Keeping the whole attribute avoids silently corrupting candidate URLs with a simplistic comma split. If your output needs one record per candidate, use a parser that follows the srcset grammar; do not assume that splitting on commas is safe for every value.

This pass does not execute page JavaScript. A successful HTTP response also does not mean the browser has fetched every declared image: lazy-loaded images may not load until they approach the viewport.

Inspect lazy-load attributes without assuming a standard

Record standard attributes such as src, srcset, and loading. When those contain a placeholder or appear incomplete, inspect the element’s other data-* attributes too. Some sites store a later image URL in a custom attribute such as data-src, data-lazy-src, or data-original. These are site conventions, not a universal HTML rule, so no fixed list will cover every site.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Python example preserves all attributes in its attributes field. To review likely custom URL fields, inspect keys beginning with data- and look at their values in context; do not automatically treat every such value as an image URL.

Use a rendered browser pass for JavaScript and responsive images

When the initial response is incomplete, collect from the page after its scripts have run. In a browser’s developer-tools console, this snippet inventories image elements, their attributes, their enclosing picture sources, and the browser-selected image URL where available:

(() => {
  const abs = value => {
    if (!value) return null;
    try { return new URL(value, document.baseURI).href; }
    catch { return value; }
  };

  const images = [...document.images].map(img => ({
    element: "img",
    page_url: location.href,
    src: abs(img.getAttribute("src")),
    srcset: img.getAttribute("srcset"),
    currentSrc: img.currentSrc || null,
    loading: img.getAttribute("loading"),
    attributes: Object.fromEntries(
      [...img.attributes].map(a => [a.name, a.value])
    ),
    picture_sources: img.parentElement?.tagName === "PICTURE"
      ? [...img.parentElement.querySelectorAll("source")].map(source => ({
          src: abs(source.getAttribute("src")),
          srcset: source.getAttribute("srcset"),
          media: source.getAttribute("media"),
          type: source.getAttribute("type"),
          attributes: Object.fromEntries(
            [...source.attributes].map(a => [a.name, a.value])
          )
        }))
      : []
  }));

  return images;
})()

currentSrc reports the image URL selected by the browser for the current page conditions; it is not a substitute for preserving every declared srcset or picture alternative. The snippet returns srcset as a raw attribute for the same reason: enumerate its candidates with a grammar-aware parser if the task requires separate candidate rows.

When images load as you scroll

Some pages defer loading until an image nears the viewport, and the page’s load event can happen before lazy-loaded images finish loading. If the first rendered snapshot is incomplete, scroll in bounded steps and collect again after each step. Keep the original page URL and element attributes with each observation, and stop when additional passes produce no new candidates or when you reach a limit appropriate to the task.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Google’s guidance on lazy-loaded content emphasizes making content available as it becomes visible. For extraction, the practical implication is to inspect the rendered page and advance through content that is only supplied as the user scrolls.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Separate finding image URLs from identifying tracking pixels

First build the candidate inventory; then, if relevant, flag items for review. A tiny rendered size, hidden styling, URL pattern, or surrounding page context may be a clue, but no single signal establishes that an image is a tracking pixel. Small images can also be icons or other interface assets. Keep the observations—such as declared URL, rendered dimensions, and visibility—separate from any classification.

The WHATWG HTML Standard discusses an anti-tracking concern related to lazy loading: image requests can reveal information about scrolling behavior. That concern explains why loading behavior matters; it does not provide a universal pixel-size threshold or a reliable automatic classifier.

Know what the inventory leaves out

A response parser sees only the returned markup. A browser pass sees only the page state reached during that run. Content behind authentication, interaction-gated galleries, or site-specific loading behavior may need additional handling. This workflow inventories image elements and their declared sources; it does not claim to extract every visual asset rendered by every possible page mechanism.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Save the page URL, element type, original attributes, and the attribute that supplied each candidate.
  • Resolve relative URLs against the document base URL.
  • Preserve raw responsive declarations unless using a parser that correctly handles their grammar.
  • Repeat collection after scripts run or scrolling reveals more content.
  • Label pixel-like items as candidates for review, not confirmed trackers.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.