Trustpilot Scraper: Reviews & Ratings

A trustpilot scraper tested live in 2026: the JSON-LD route returns 20 reviews per business with no API key, plus what robots.txt and the ToS say.

MMotherlode Lab9 min read
Magpie title card: Trustpilot Scraper: Reviews & Ratings

Trustpilot hides its data in plain sight. Every business page ships a server-rendered JSON-LD block holding the twenty most recent reviews in full (author, star rating, timestamp, complete text) next to the React app that displays them. A trustpilot scraper does not need to touch the app at all.

I tested three routes against live pages on October 16, 2026, from a home connection: a one-command JSON-LD extraction with no API key, a browser-render fallback for the profile stats the JSON-LD skips, and the generic routes that fail. Scorecard below, with the exact commands and what came back.

The rules first, because Trustpilot is the most openly hostile of the review sites. Its robots.txt file is 25 KB of specific carve-outs for Google, and the generic section is one line: Disallow: / for everyone else. The current Terms of Use are blunt: “You must not carry out in any way (including facilitating, permitting or authorising) any text mining, data mining or web scraping of our platform for any purpose without our express permission.”

None of this is legal advice; Is Web Scraping Legal? covers the plain-English version. Everything below documents what happened when I ran these commands. What you run, and why, is your call.

What Trustpilot’s rules say, and what my crawler did about it

Three layers of written rules, each stricter than the last:

  • robots.txt: User-agent: * gets Disallow: /, the entire site. Googlebot gets a long specific list and can still read /review/<domain> pages (only /review/*/transparency and query-string variants like ?sort= are blocked for it). Translation: Google may index review pages; generic bots are told no.
  • Terms of Use: automated collection is prohibited without Trustpilot’s approval. This is the binding document between you and them, and it is stricter than robots.txt.
  • The official API: Trustpilot runs a documented REST API at developers.trustpilot.com, but keys are issued through Trustpilot business accounts. You get programmatic access to your own reviews, not a pipe for collecting your competitors’.

Magpie’s crawler enforces the first layer on your behalf. Pointing it at a Trustpilot seed fails before a single request:

$ magpie crawl "https://www.trustpilot.com/review/dbrand.com" --max-pages 1 --corpus
Error: crawl: seed www.trustpilot.com: robots.txt disallows crawl

There is a --ignore-robots flag that fetches anyway with a printed warning. I left it alone, and this page stays single-URL throughout. Bulk crawling Trustpilot is the one thing I will not walk you through, because it is the thing their robots.txt and ToS both refuse in writing. If your job is monitoring a competitor’s reviews, scraping without getting blocked covers the ethics and pacing of the polite version.

The JSON-LD route: twenty reviews, one static request

Open any review page’s source and search for application/ld+json. You will find two script blocks whose @graph holds a LocalBusiness node for the reviewed company (name, address, aggregateRating) plus twenty full Review nodes. On the dbrand page I pulled today, that node reads ratingValue: 4.5, reviewCount: 13686.

This block exists for Google’s rich results, which means it is server-rendered, stable, and free to read. No render, no login, no key.

Magpie’s trustpilot vertical parses exactly this block. The command:

$ magpie vertical "https://www.trustpilot.com/review/www.amazon.com"

The URL alone is enough: the vertical auto-dispatches on the trustpilot.com/review/{domain} pattern, no --name flag required. What came back (abridged):

{
  "url": "https://www.trustpilot.com/review/www.amazon.com",
  "title": "Amazon Reviews | Read Customer Service Reviews of www.amazon.com",
  "vertical": "trustpilot",
  "record": {
    "name": "Trustpilot",
    "reviews": [
      {
        "author": "Eric Patterson",
        "body": "Friendly and helpful team",
        "date": "2026-10-16T11:47:26.000Z",
        "rating": 4
      },
      {
        "author": "Richard",
        "body": "If you purchase an item 5 or 6 weeks ago coming from the USA...",
        "date": "2026-10-16T11:41:47.000Z",
        "rating": 1
      }
    ]
  }
}

Twenty reviews per call, newest first, on both pages I tested (Amazon and dbrand). Each review carries four fields:

Field What it holds Example from the live run
author Reviewer display name Eric Patterson
rating Star value, 1–5 integer 4
date Review timestamp, ISO 8601 UTC 2026-10-16T11:47:26.000Z
body Complete review text "Friendly and helpful team"

The same record is available through the regular scrape command with --vertical trustpilot, which is the form to use when you want the fuller envelope (final_url, title) alongside the record. Zero LLM calls either way. This is the same zero-key path the event scraper and Reddit guides use, and it needs no LLM provider configured.

Why does this work when the page is otherwise a JavaScript app? The JSON-LD ships in the initial HTML for Googlebot’s benefit. Everything else, from filters to the star breakdown to the infinite scroll into older reviews, renders client-side.

The JSON-LD block is the one slice of Trustpilot that behaves like a 2005 website, so the extraction is a single static fetch. It ran first try on both businesses, no flags, no cookies.

What the vertical gets wrong today

Four limits, all verified against magpie v0.1.32 today. Check the current version before you depend on any of them.

The name field says “Trustpilot” for every business. The extractor takes the first Organization node in the JSON-LD, and on current pages that node is Trustpilot itself, the publisher. The reviewed company’s name sits on the LocalBusiness node instead, which the extractor does not read. Amazon, dbrand, whoever: the record’s name is Trustpilot. You get the real name from the page title or the URL slug.

TrustScore and review count come back empty. The code has rating_value and review_count keys for exactly this data, and the page’s LocalBusiness node carries it (4.5, 13686 for dbrand today). But the extractor only walks Organization nodes, and no current Organization node has an aggregateRating child. The keys exist; the values never arrive. Same root cause as the name bug, same fix.

Twenty reviews is a hard ceiling. The JSON-LD holds page one only. ?page=2 changes nothing (I re-ran it and got the identical twenty authors), and the reason is visible in the source: the extractor builds the fetch URL from the path alone and drops the query string. Older reviews load through client-side pagination that the JSON-LD never sees.

Country domains do not match. uk.trustpilot.com/review/dbrand.com fails with vertical extractor does not handle URL; the host check accepts only trustpilot.com and www.trustpilot.com. The path-based fetch means any country-domain URL would have pulled the .com page anyway.

Two smaller gaps worth knowing: no verified-reviewer badge, no business replies, and no reviewer location in the JSON-LD (the rendered page shows all three). And a fake business fails loudly rather than returning an empty record: vertical: trustpilot: no JSON-LD on …, exit 1. That is the correct behavior for a scraper you pipe into something else.

When you need the whole profile: render the page

The static route answers “what do customers say.” The rendered page answers “what does this profile look like,” and that is a different dataset. Rendering dbrand’s page with a real browser and extracting the markdown:

$ magpie scrape "https://www.trustpilot.com/review/dbrand.com" --render browser

The markdown that came back (abridged) includes everything the React app hydrates: the 13,686 review total, Replied to 89% of negative reviews, Typically replies within 1 week, the invitation badge (Asks customers to review), Trustpilot’s AI-generated review summary, and the full text of all twenty reviews with their “from Malaysia”-style reviewer details. The structured-data sidecar carries the same JSON-LD block the vertical reads, aggregate rating included.

Cost: this launches a real Chromium per page via go-rod, so it is the slow route. It is also the only route for the profile stats, because without the render the generic markdown extraction dies in magpie’s quality gate. I tried it: clean: extract: text and comments are not long enough: 0 0, exit 1. The server-rendered shell has no readable text; the app is the content.

That gate is a feature. It refuses to hand you an empty page and call it a scrape. Scraping dynamic websites explains when a render is worth the launch cost and when it is not.

The rules apply to this route identically. A browser render of a public page is the same fetch with JavaScript attached. Robots.txt says no to bots here either, and the ToS has not changed. I am documenting what the tools do, not advising the run.

The other trustpilot scrapers, and when they fit

The Google results for this query are a wall of tool roundups (Thunderbit’s October 2026 list is typical), and none of them mention the JSON-LD block. They jump straight to paid tooling. For completeness, the categories:

  • The official API: the only clean answer for bulk history, if the business is yours. You claim the profile, get a key, and pull reviews through documented endpoints.
  • Hosted scrapers: Apify (Trustpilot actors, $5 free credits, Starter $9/month), Octoparse (free tier: 10 tasks, Standard $69/month), ScraperAPI (proxy/render infrastructure for your own code, Hobby $49/month), Thunderbit (Chrome extension, free for 6 pages/month, $15/month paid). Prices from their October 2026 roundups. These exist because collecting at scale means proxies, anti-bot handling, and maintenance: the parts that get expensive exactly when Trustpilot pushes back. That is their job, and they charge for it.
  • Open-source Python: packages like trustpilot-scraper on PyPI parse the same embedded JSON this page covers and hand you Python objects instead of JSON on stdout. Right choice if Trustpilot is one stop in a larger Python pipeline. Wrong choice if you were about to build pagination, retries, and polite pacing by hand. That is the Reddit scraper story again, and the maintenance bill lands later.

If the JSON-LD route covers your volume — one profile, latest twenty, checked on demand — paying monthly for a hosted actor is hard to justify. If you need years of history for sentiment analysis, no free route gets you there, and the honest options shrink to the official API or a hosted service that owns the compliance question.

FAQ

Is it legal to scrape Trustpilot reviews? Trustpilot’s Terms of Use prohibit collecting content by automated means without approval, and robots.txt disallows all bots except Google. Public data is not automatically free data. The legal exposure depends on your jurisdiction and use; that page covers the general landscape, and this is not legal advice.

Can I scrape Trustpilot without an API key? Yes. The JSON-LD block in every review page’s HTML holds the twenty latest reviews, server-rendered. One static request returns them: no key, no login, no JavaScript. That is exactly what the vertical command in this guide does.

How do I get more than the latest 20 reviews? Not from the JSON-LD. Pagination is client-side and page one is all it ships. Your options: the official API if the business is yours, a hosted scraper if it is not, or a browser render for a few more pages at slow, polite, manual scale.

Why does my scraper return empty HTML on Trustpilot? You fetched the React shell. The visible content hydrates in the browser after JavaScript runs. Either parse the JSON-LD block that ships in the initial HTML, or render the page in a real browser before extraction.

Does the scraper get the TrustScore? Not today, from the JSON-LD route. The score and count live on a node the current extractor skips, so read them from the rendered page or the page title until the extractor catches up.

Where this leaves you

One profile, latest reviews, on demand: magpie vertical "https://www.trustpilot.com/review/<domain>" and you are done in one static request. The business’s own review history: the official API. Competitor history at bulk scale: that is where I stop, because robots.txt, the ToS, and polite practice all point the same direction. And if your real target turns out to be ratings on a friendlier site, the Amazon scraper guide covers the review-adjacent fields that one does expose.

Stop renting credits.

One flat price, your machine, your keys.

Download free for Windows, macOS and Linux

Windows · macOS · Linux $49/mo flat, cancel anytime