CrawlForge MCP
首页Playground应用场景集成价格文档博客
CrawlForge MCP v5.2.0: Shopify Product Data Without Parsing HTML
Product Updates
返回博客
产品更新

CrawlForge MCP v5.2.0: Shopify Product Data Without Parsing HTML

C
CrawlForge Team
工程团队
2026年8月26日
阅读时长 11 分钟

本页内容

快速解答

CrawlForge MCP v5.2.0 is a minor release centred on product extraction. The new shopify-product template reads a store's own /products/<handle>.json rather than the rendered page, returning exact price, compare-at price, per-variant stock, options, images and tags from any Shopify storefront including custom domains. scrape_template can now fetch a JSON endpoint instead of HTML; fetch_url reports responseTime; crawl_deep reports cached and crawled_at; and Ollama finally works as an LLM provider with no cloud API key. Major fixes: amazon-product returned nulls against every current Amazon page, track_changes scored price moves by page share so monitors never fired, and scrape_with_actions carried seven Playwright defects. Tool count stays at 28, nothing breaks, and scrape_template is still 1 credit. Upgrade with npm install -g crawlforge-mcp-server@latest.

Every one of our amazon-product tests passed. The tool returned null for the price currency, null for the rating, null for every image, and the string "Brand: Amazon" where the brand should have been. Nothing was broken in CI, because the fixtures had been written to match the selectors instead of the site.

CrawlForge MCP v5.2.0 is largely a release about that. One new template, three tools that now report facts they always had, and a long run of fixes to things that were quietly wrong while their tests were green.

Table of Contents

  • What Shipped
  • The Bug That Passed Six Tests
  • Shopify Prices Without Parsing HTML
  • Templates Can Now Read an API
  • Price Monitoring That Notices Prices
  • Two Tools Report What They Always Knew
  • Browser Automation Against Real Playwright
  • Local LLMs Actually Work Now
  • One Copy of the Extractors
  • Credit Costs
  • How to Upgrade

What Shipped

ChangeToolImpact
New shopify-product templatescrape_templateExact price, compare-at price and per-variant stock from any Shopify store
Templates can read a JSON endpointscrape_templateA template can fetch structured data instead of HTML
amazon-product rebuilt from live pagesscrape_templateCurrency, rating, review count, brand and full-size images actually return
Price moves scored by magnitudetrack_changesA price monitor set up the obvious way now fires
customSelectors scopes the comparisontrack_changesSelector scoping narrows the diff instead of widening it
responseTime in the responsefetch_urlLatency checks without a second tool
cached and crawled_atcrawl_deepA replayed crawl is distinguishable from a fresh one
Ollama registered as a providerextract_structured, deep_researchLocal models work with no cloud API key
Seven Playwright defects fixedscrape_with_actionsScroll-to-element, waits, retries and recovery all run
Renderer leak closedstealth_modeThe hosted browser stops running itself out of memory

Tool count stays at 28. No schema, output-shape or credit-cost change to any existing tool — this is a drop-in upgrade. The suite is 1,122 unit tests, 1,121 passing, and MCP protocol compliance is 100% across all 28 tools.

The Bug That Passed Six Tests

amazon-product was the worst case, so it is worth being specific about how it failed.

Run against three live Amazon pages, the template returned null for currency, null for rating, null for images, null for breadcrumbs, "Brand: Amazon" for the brand and the literal string "(198,594)" for the review count. Six unit tests covered it. All six passed.

They passed because every selector they exercised — a priceCurrency meta tag, #acrPopover .a-size-base, img.a-thumbnail-image — exists nowhere on Amazon today, and the fixture HTML had been written to contain them. The tests were checking that our code agreed with itself.

The fix was to capture three real pages — a first-party device, a branded storefront and a book — and re-derive every selector from what Amazon actually serves:

  • Currency comes from the hidden add-to-cart form field, not a meta tag.
  • Rating is parsed to a number from the title attribute on #acrPopover, so you get 4.7 rather than "4.7 out of 5 stars".
  • Review count is parsed from either "(198,594)" or "198,594 global ratings" — Amazon uses both — and returns 198594.
  • Brand reduces all three byline shapes to the bare name.
  • Images drop Amazon's size token from the URL. The tokened URL is a 1 KB thumbnail; the same URL without it is the 16 KB original.

The rewritten suite has 24 tests, and 15 of them fail against the pre-fix code. That is the property the old suite lacked.

Shopify Prices Without Parsing HTML

The headline addition is a shopify-product template, and it exists because every Shopify failure we hit this cycle came from parsing the rendered page.

Shopify's Dawn theme ships every price badge in the markup unconditionally and hides the inapplicable ones with component CSS. A scraper reading the DOM sees a "Sold out" badge on a product with a hundred units in stock. Ask an LLM for a compare-at price on a product that has none and it will produce a plausible one — in our testing it invented 27.99.

So the template does not read the page. Shopify serves the same data as JSON at /products/<handle>.json, on every storefront including custom domains, and that is what it reads:

Json
{
  "tool": "scrape_template",
  "params": {
    "template": "shopify-product",
    "url": "https://shop.example.com/products/kelpie-bandana"
  }
}

You get the exact price, the compare-at price, on_sale, currency, the price range across variants, per-variant stock, options, images and tags — with no HTML parsing and no LLM anywhere in the path.

Storefronts differ in ways that only show up against real stores, and the template handles the ones we found in live captures:

  • An absent compare-at price is "" on one store and "0.00" on another. Both read as null, because both render no badge — while a genuinely free product keeps its 0.00 price.
  • Tags arrive as an array on some stores and a comma-joined string on others.
  • The endpoint carries no available flag at all. Stock is derived from inventory management, inventory policy and quantity together, and reports null rather than guessing "in stock" when the payload does not say.

Point it at a site that is not Shopify and it fails with a clear message instead of returning a row of empty fields.

Templates Can Now Read an API

shopify-product needed something the template system could not do: fetch something other than the page the caller named. Rather than let one template open its own socket — which would have put it outside the SSRF guard — TemplateRegistry gained two optional hooks.

resolveUrl(url) redirects the tool's single fetch, and extractRaw(body, url) parses a non-HTML response. The tool still owns the fetch, the guard and the timeout. When a rewrite happens, the response reports the URL that was actually read as fetchedUrl, so nothing is hidden from the caller.

HTML templates are untouched. But the door is now open for any site that publishes structured data next to its rendered page, which is most storefront platforms.

Price Monitoring That Notices Prices

track_changes had a flaw that made its main use case not work.

Change significance was purely volumetric — scored by how much of the page had changed. A price is a handful of characters, so $19.99 → $29.99 and $19.99 → $99.99 both scored "minor". With notificationThreshold defaulting to "moderate", a price monitor configured the obvious way never fired. Unscoped, the change often did not register at all.

Monetary amounts are now compared as numbers, and their relative magnitude raises significance to at least "moderate" — or "major" past 20%. Only currency-tagged numbers count, so view counters and review totals do not trip it, and thousands separators parse, so $1,299 reads as 1299. The before-and-after pair is surfaced in details.valueChanges, so you can see why a monitor fired rather than guessing.

Two more in the same tool:

customSelectors never scoped anything. It was read only inside section-level analysis, where it added hashes. Scoping a comparison therefore made it worse: on an Amazon product page, scoping to the price block took modified elements from 456 to 3,204 and the payload from 5.35 MB to 6.18 MB — and reported changes on a page whose price had not moved. Analysis now narrows the document to the matched subtrees, so hashing, similarity and diffs are all scoped together. A selector that matches nothing falls back to the whole document and says so.

structuralSimilarity reported 0 when it had not measured anything. Zero is a real score meaning the structure changed completely, so opting out of structural tracking produced the strongest possible signal that the structure had changed. It is null when not measured.

Two Tools Report What They Always Knew

fetch_url returned status, headers, body, size and content type — enough to answer "is this URL up?" and nothing that could answer "how slow is it?", despite being the raw-HTTP tool with nothing else to fall back on. It now returns responseTime.

The measurement is more careful than a stopwatch around the call. It starts after the per-host politeness throttle, so a monitor polling one host in a loop does not read its own waiting as the site being slow, and it closes after the body is fully read, so a server that answers instantly and then trickles is correctly reported as slow. Live: example.com at 96 ms, our own health endpoint at 547 ms.

crawl_deep gains cached and crawled_at. A replayed crawl used to be indistinguishable from a fresh one; crawled_at now carries when the pages were really fetched. Both are declared in the tool's output schema.

The same two fields have landed on the hosted REST API this week, so a latency check reads the same on either surface:

Bash
curl -X POST https://www.crawlforge.dev/api/v1/tools/fetch_url \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'

Browser Automation Against Real Playwright

scrape_with_actions carried seven defects, none of which its test suite could see — because its fake pages implemented whatever the executor called, including APIs Playwright does not have.

scroll toElement called scrollIntoView(), which exists on neither a handle nor a locator, so that branch threw every single time it ran. The wait action advertised enabled, disabled and stable and passed them to an API that rejects them. A per-action Promise.race shared its deadline with the work it was racing and won, replacing Playwright's real error with a bare "Action timeout" and leaking a timer per action. Clicks and keypresses did not wait on the document they replaced. A chain retry replayed against whatever the failed attempt had left behind instead of reloading. And every recovery strategy sat behind retries > 0 while the schema defaulted retries to 0, so not one of them could ever run.

The new suite drives a real Chromium against a local fixture server, and skips cleanly when no browser binary is installed.

stealth_mode had a matching problem in production rather than in tests: create_page never closed its page, leaking a Chromium renderer per call until the hosted instance ran out of memory. A wedged browser was then reused forever behind truthiness-only checks, and cleanup hung on protocol calls to the dead browser, so it could not be unwedged remotely either. v5.2.0 adds corpse detection via isConnected(), a disconnect handler, cleanup that races closes against 5-second deadlines with a SIGKILL fallback and pool recreation, and a mutex around in-flight launches.

Local LLMs Actually Work Now

LLMManager registered OpenAI and Anthropic and nothing else, both gated behind an API key. On a machine running Ollama with no cloud keys, extract_structured skipped LLM extraction entirely and quietly reported css_fallback — producing values like "$79.99$79.99" and dropping fields — while deep_research silently disabled query expansion, semantic ranking and synthesis. extract_with_llm has its own private client, which is why it kept working and masked the gap for so long.

Ollama is now a registered provider. A failed LLM call also stops reporting extraction_method: "llm" with confidence 0.9.

Model selection changed too. Routing hardcoded llama3.2. Benchmarked against three live product pages with verified ground truth, gemma3:4b scored 18/18 at 1,040 ms while llama3.2 scored 16/18 — and its failures were systematic rather than sampling noise: across five runs it invented a compare-at price all five times. Parameter count did not predict accuracy at all. The 4B model beat both a 12B and a 20B. selectOllamaModel() now picks the highest-ranked installed model, and OLLAMA_DEFAULT_MODEL still overrides it.

For hosted setups, every Ollama HTTP call now sends Authorization: Bearer when OLLAMA_API_KEY is set, so a deployment can point at Ollama Cloud or any auth-fronted instance with no OpenAI or Anthropic key at all. Unset, nothing changes.

One Copy of the Extractors

The last change in this release is structural, and it is the reason the amazon-product story could happen twice.

This server and the CrawlForge REST API each carried their own copy of the same eleven site extractors, written in two different languages, with nothing detecting divergence. It diverged twice in two days: amazon-product was repaired here and the REST copy kept returning nulls, and shopify-product existed on one side only.

There is now one implementation, published as crawlforge-extractors, which both surfaces install. TemplateRegistry is re-exported from it with an unchanged API — nothing about the scrape_template tool changes for callers. The per-template tests moved with it.

The alternative was a parity test that told us after the fact which copy was wrong. Deleting the second copy is cheaper than detecting drift in it.

Credit Costs

Nothing changed. scrape_template remains 1 credit per call regardless of which template you use, fetch_url is 1, and track_changes is 3. Failed requests are never charged.

The free plan includes 1,000 one-time credits, which is 1,000 template scrapes — enough to pull a full Shopify catalogue before deciding anything.

How to Upgrade

Bash
npm install -g crawlforge-mcp-server@latest
crawlforge --version   # 5.2.1 or newer

If your MCP client launches the server with npx, it picks up the release on the next restart. There are no breaking changes: no tool was renamed, no output shape changed, and no credit cost moved.

Update: 5.2.1 followed the same day. Two of the fixes above had reached the hosted server on release day but not the npm tarball — shopify-product was missing from the tool description an MCP client reads when it picks a template, and structuralSimilarity could not score below 0.5 because the hierarchy half of it compared an object nothing ever wrote to. Take @latest.

Want structured product data without writing a selector? Start free with 1,000 credits, then read the scrape_template API reference for the full template list and field-by-field output.

亲自试一试——无需注册

在 Playground 中运行 CrawlForge 的 28 个抓取与提取工具中的任意一个,然后免费开始,获取 1,000 credits。

1,000 免费 credits • 一次性 • 无需信用卡

标签

releasev5.2.0shopifyscrape_templateMCPweb scrapingchangelog

关于作者

C

CrawlForge Team

工程团队

我们正在打造功能最全面的 Web 抓取 MCP server。我们开发的工具帮助开发者为 AI 应用提取、分析和转换 Web 数据。

及时获取最新洞察

将教程、产品更新与 Web 抓取技巧直接发送到你的收件箱。

拒绝垃圾邮件,随时可取消订阅。

付诸实践

在任意 URL 上测试 CrawlForge 的工具——免费,无需注册。

本页内容

Frequently Asked Questions

What is new in CrawlForge MCP v5.2.0?+

v5.2.0 adds a shopify-product template that reads a store's own /products/<handle>.json for exact prices, compare-at prices and per-variant stock; gives scrape_template the ability to fetch a JSON endpoint instead of a page; adds responseTime to fetch_url and cached/crawled_at to crawl_deep; supports remote Ollama endpoints via OLLAMA_API_KEY; and fixes a long list of defects including an amazon-product template that returned nulls against every current Amazon page, price monitoring that never fired at its default threshold, and seven Playwright defects in scrape_with_actions. Tool count stays at 28 and no existing tool changed shape or price.

Why read /products/<handle>.json instead of scraping the Shopify page?+

Because the rendered page lies about stock and price. Shopify's Dawn theme ships every price badge in the markup unconditionally and hides the inapplicable ones with CSS, so a DOM scraper reads a "Sold out" badge on a product with stock. Asking an LLM to read a compare-at price that does not exist produces an invented one. The JSON endpoint is the store's own data, served on every storefront including custom domains, so the price, the compare-at price and the per-variant inventory are exact rather than inferred.

Does upgrading to v5.2.0 break anything?+

No. No tool was renamed, no output shape changed and no credit cost moved, so it is a drop-in upgrade. The additions are new fields on existing responses — responseTime on fetch_url, cached and crawled_at on crawl_deep, fetchedUrl on scrape_template when a template redirects its own fetch. Run npm install -g crawlforge-mcp-server@latest, or restart your MCP client if it launches the server with npx.

How did the amazon-product template pass its tests while returning nulls?+

The fixtures had been written to match the selectors rather than the site. Every selector the tests exercised — a priceCurrency meta tag, #acrPopover .a-size-base, img.a-thumbnail-image — exists nowhere on Amazon today, but the fixture HTML contained them, so the tests were checking that the code agreed with itself. The template was rebuilt from captures of three live Amazon pages, and its new 24-test suite was written so that 15 of those tests fail against the pre-fix code.

Do I need an OpenAI or Anthropic key to use the LLM-backed tools?+

Not any more, if you run Ollama. LLMManager registered only OpenAI and Anthropic, both gated behind an API key, so on a machine running Ollama with no cloud keys extract_structured silently fell back to CSS extraction and deep_research quietly disabled query expansion, ranking and synthesis. Ollama is now a registered provider, model routing picks the best installed model rather than hardcoding llama3.2, and OLLAMA_API_KEY lets a hosted deployment point at Ollama Cloud or any auth-fronted instance.

What does the shopify-product template cost?+

1 credit per call, the same as every other scrape_template template, and failed requests are never charged. The free plan's 1,000 one-time credits are therefore 1,000 template scrapes. It is available over MCP, over the REST API at /api/v1/tools/scrape_template, and in the browser playground with no setup.

相关文章

CrawlForge MCP v5.2:28 个工具的全部变更
Product Updates

CrawlForge MCP v5.2:28 个工具的全部变更

两天六个版本,全部来自把 28 个工具对准真实网站,而不是信任测试套件:新增 Shopify 模板,PullPush 停摆后重建 Reddit 全站搜索,价格监控终于会触发,Ollama 成为真正的 LLM 提供方。CrawlForge MCP v5.2 的每一处变更,都在这里。

C
CrawlForge Team
|
8月26日
|
16 分钟
CrawlForge MCP v5.1.0:无需 API 也能搜索 Reddit
Product Updates

CrawlForge MCP v5.1.0:无需 API 也能搜索 Reddit

reddit.com 挡住了我们手上的每一种抓取方式 — 所以 v5.1.0 推出第 28 个工具 reddit_search:通过社区归档搜索帖子和评论、读取完整讨论串。无需 Reddit API key,无需任何凭证,每次调用 5 credits。

C
CrawlForge Team
|
8月24日
|
9 分钟
CrawlForge v5.0.4:实测全部 27 个 MCP 工具,修复 34 个缺陷
Product Updates

CrawlForge v5.0.4:实测全部 27 个 MCP 工具,修复 34 个缺陷

一天之内四个补丁版本:我们针对真实网站实测了全部 27 个 MCP 工具和每一个 CLI 子命令,并修复了发现的全部 34 个缺陷。

C
CrawlForge Team
|
8月20日
|
10 分钟

页脚

CrawlForge MCP

面向 AI Agent 的企业级网页抓取。28 个专业 MCP 工具,专为构建智能系统的现代开发者而设计。

产品

  • 功能
  • Playground
  • 价格
  • 应用场景
  • 集成
  • 替代方案
  • 更新日志

资源

  • 快速上手
  • API 参考
  • 模板
  • 指南
  • 博客
  • 术语表
  • 常见问题
  • 网站地图

开发者

  • MCP 协议
  • Claude Desktop
  • Cursor IDE
  • LangChain
  • LlamaIndex

公司

  • 关于我们
  • 联系我们
  • 隐私政策
  • 服务条款
  • 可接受使用政策
  • Cookie

保持更新

获取新工具和新功能的最新动态。

基于 Next.js 和 MCP 协议构建

© 2025-2026 CrawlForge。保留所有权利。