L logiover
data · Jul 9, 2026 · 7 min read

How to Extract Structured Data from Any URL in 2026

Turn any web page into clean JSON without an LLM: parse schema.org JSON-LD, OpenGraph, tables, prices and contacts deterministically — no API key, no browser.

Most “extract fields from a page” jobs get solved the expensive way: fire the HTML at an LLM, write a prompt, pray it returns valid JSON, and pay per token every time. But the vast majority of product pages, articles, recipes, events and business listings already ship their structured data baked into the markup — as schema.org JSON-LD, OpenGraph tags and microdata that a search engine crawler reads for free. You don’t need a language model to guess at fields that are sitting in a script tag. This guide covers how to pull that structured data deterministically from any URL — the same signals Google reads — without an LLM, an API key, or a browser.

What’s worth extracting

This actor returns exactly one consolidated JSON record per URL. The useful parts:

  • extracted — a flattened convenience object with the fields you usually want: title, description, price, currency, brand, author, publishedDate, ratingValue, image, merged from JSON-LD and OpenGraph. This is what most agents read first.
  • jsonLd — every application/ld+json block on the page, parsed and @graph-flattened, tolerant of malformed JSON. Covers Product, Article, Recipe, Event, Organization, BreadcrumbList and more.
  • openGraph — all og:* and twitter:* meta as one object (the social-card data).
  • meta — title, description, author, published/modified dates, canonical URL, language, favicon, image, keywords.
  • prices — an array of price objects with value, currency and the raw string, read from JSON-LD offers first and multi-currency regex second.
  • tables — each HTML table converted to an array of row objects, using the header row as keys.
  • contacts — emails and phone numbers found via mailto/tel links and text heuristics.
  • headings, images and (opt-in) links — page structure and in-content media as absolute URLs.

Every record also carries url, finalUrl (after redirects), statusCode, an error field, and a fetchedAt timestamp. Seventeen structured fields per URL, all from markup the page already publishes.

How the source actually works

There is no single “source site” here — the source is any URL you hand it. What makes deterministic extraction possible is that structured metadata is a web standard, not an afterthought. Publishers embed it precisely so machines can read their content:

  • JSON-LD lives in script type="application/ld+json" blocks and is the richest source. A product page’s price, currency, brand and rating are almost always in there as a Product object with an offers node.
  • OpenGraph and Twitter meta live in the page head and drive link previews on social platforms — title, image, type, description.
  • Microdata (itemscope / itemprop) and plain meta tags fill the gaps.

The actor fetches server-rendered HTML over plain HTTP through Apify’s datacenter proxy, then parses these signals directly. No V8, no headless Chrome, no LLM inference. Because JSON-LD and OpenGraph are almost always present in the initial HTML (search crawlers need them there), a plain fetch covers the large majority of pages.

A minimal single-URL input:

{ "helloWorld": 123 }

That placeholder does nothing — the only real requirement is at least one URL. A realistic product-monitoring input:

{
  "urls": ["https://www.apple.com/shop/buy-iphone/iphone-16-pro"],
  "fields": ["price", "brand", "rating"],
  "extractJsonLd": true,
  "extractTables": true
}

The optional fields array is a best-effort, case-insensitive request: name what you want (price, author, rating) and the actor maps it against JSON-LD, meta and the flattened extracted object, returning it under requestedFields. It never fails if a field is missing — it returns null for it instead.

Open AI Web Extract on Apify — give it a URL, get one clean JSON record back: JSON-LD, OpenGraph, tables, prices and contacts. No LLM, no API key, no browser. Pay per extracted page.

The access reality: what deterministic parsing does and doesn’t cover

Being honest about the boundaries matters more than hype here.

  • It reads server-rendered HTML, not client-rendered apps. It does not execute JavaScript. For a heavy single-page app that renders everything client-side, the structured data may not be in the initial HTML — use a browser-based scraper for those. In practice, JSON-LD and OpenGraph almost always ship in the initial HTML precisely because crawlers read it, so this covers most of the web.
  • Datacenter proxy is the default. It routes through Apify’s datacenter proxy (AUTO) to avoid per-IP rate limits. For bot-walled sites, set proxyGroups to RESIDENTIAL.
  • Batch is capped at 500 URLs per run, with concurrency tunable 1–20 (lower for fragile sites, higher for throughput).
  • It does not bypass logins or paywalls. It reads what a browser or search crawler already sees — nothing gated.
  • Zero hallucinations, but also zero inference. Deterministic parsing means it never invents a value; it also won’t “reason” a price out of prose that has no structured markup. If a page ships no structured data, you still get meta, headings and tables, but the rich fields will be sparse.

Crucially, every URL produces a row — even a failed fetch returns a record with an error field, so nothing is silently dropped from a batch.

Example output

A trimmed record for a product page:

{
  "url": "https://www.apple.com/shop/buy-iphone/iphone-16-pro",
  "statusCode": 200,
  "title": "Buy iPhone 16 Pro and iPhone 16 Pro Max",
  "extracted": {
    "title": "iPhone 16 Pro",
    "price": "999",
    "currency": "USD",
    "brand": "Apple",
    "image": "https://www.apple.com/v/iphone-16-pro/a/images/overview/hero.jpg"
  },
  "jsonLd": [
    { "@type": "Product", "name": "iPhone 16 Pro", "offers": { "price": "999", "priceCurrency": "USD" } }
  ],
  "openGraph": { "og:title": "iPhone 16 Pro", "og:type": "product" },
  "prices": [{ "value": 999, "currency": "USD", "raw": "999" }],
  "contacts": { "emails": [], "phones": [] },
  "requestedFields": { "price": "999", "brand": "Apple", "rating": null },
  "fetchedAt": "2026-07-06T09:14:22.183Z"
}

Note rating came back null under requestedFields — the page had no rating in its markup, and the actor reports that honestly rather than fabricating one.

Typical use cases

  • AI agent “extract from URL” tool — give an agent a structured-data tool it calls mid-conversation, paying per page. This is the primary design target.
  • E-commerce and price monitoring — pull product name, price, currency, availability and rating from any product page via its JSON-LD offers.
  • RAG and knowledge bases — ingest clean structured facts, not noisy HTML, before chunking and embedding. Cleaner input, better retrieval.
  • Content and metadata harvesting — grab titles, authors, publish dates and OpenGraph cards for articles and news at scale.
  • Lead and contact enrichment — extract emails, phones and organization data from business pages.
  • Comparison and aggregation — normalize tables and specs across many sources into consistent JSON row objects.

Build-it-yourself vs. managed actor

The parsing itself is not exotic — anyone can write a JSON-LD reader. What adds up is the long tail: @graph flattening, tolerating malformed JSON blocks (plenty of sites ship broken JSON-LD), the multi-currency price regex across 25+ currency formats, header-keyed table extraction, contact heuristics, proxy rotation, and the “every URL yields a row even on failure” contract that keeps batches clean.

On cost: this is pay-per-event — one charge per extracted URL, plus standard Apify platform usage. There’s no LLM token bill and no third-party API key to manage, which is the whole point versus an LLM-extraction approach. An agent can call it, pay for one page, and move on. For a batch of 500 URLs you’re paying for 500 events; compare that to an LLM extraction pipeline where each page is thousands of input tokens plus output tokens, every run.

Because it’s pay-per-event and keyless, it’s also MCP-ready: AI agents can discover and call it autonomously through Apify’s MCP server, one charge per page, from Claude, Cursor or any MCP client. It pairs naturally with a “read this page as Markdown” tool — use Markdown for prose, use this when you need typed fields.

Common pitfalls

  • Client-rendered pages return thin data. If a site renders its content with JavaScript after load, the structured data may not be in the initial HTML. You’ll get meta and title but sparse extracted — reach for a browser-based scraper on those specific pages.
  • Malformed JSON-LD is common but handled. Many sites ship syntactically broken ld+json. The parser is tolerant, but if a block is truly unrecoverable it’s skipped — don’t assume every declared JSON-LD block will appear in jsonLd.
  • fields is best-effort, not a schema contract. Requesting a field that the page doesn’t publish returns null, not an error. Design downstream code to tolerate nulls in requestedFields.
  • Prices come from offers first, then regex. A JSON-LD offers.price is exact; a regex-matched price from visible text ($1,299.00, 1 299,00 €, USD 49) is a heuristic. When both exist, trust the offers value.
  • extractLinks is off by default. Links are deduped and capped at 100 when enabled — turn it on deliberately, since it bloats output on link-heavy pages.
  • A row per URL means a row per failure too. Filter on statusCode and error when you process a batch, or you’ll ingest failed-fetch placeholders as if they were data.

Wrapping up

If you’re feeding an agent, a RAG pipeline or a price monitor, you rarely need a language model to read a page that already publishes its own structured data. Deterministic JSON-LD and OpenGraph parsing is faster, cheaper, and free of hallucinated values — and it degrades gracefully to meta, headings and tables when a page ships nothing richer.

Run AI Web Extract on Apify — batch up to 500 URLs into clean JSON records (JSON-LD, OpenGraph, tables, prices, contacts), one guaranteed row per URL, no LLM and no API key. Export to JSON, CSV, Excel or RSS, or call it as an MCP tool. Start on Apify’s free monthly credit.

Related guides