GTM Tool Website Scraper avatar

GTM Tool Website Scraper

Pricing

Pay per usage

Go to Apify Store
GTM Tool Website Scraper

GTM Tool Website Scraper

Per-URL enricher: renders each GTM/SaaS tool website with Playwright and returns tool_name, a <500-word plain-text summary, and any demo video (YouTube/Vimeo/Wistia/Loom/mp4/link).

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Rahul

Rahul

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

11 days ago

Last modified

Share

Build a GTM (go-to-market) tool directory at scale. Give this actor a list of tool website URLs and it returns, for each URL, a clean structured record:

  • tool_name — the company/tool name
  • summary — a plain-text description of what the tool does (deterministically kept under 500 words by default)
  • demo_video_url — the first demo/product video found on the site
  • demo_video_source — where that video lives (youtube, vimeo, wistia, loom, html5, link, or none)

It renders every site with a real headless Chromium browser (Playwright), so modern client-side-rendered React / Next.js / Webflow marketing sites work just as well as server-rendered ones.


Why this actor

Generic website-content crawlers hand you a wall of raw page text. This actor gives you exactly the three fields a GTM tool directory needs — name, a concise "what it does" summary, and the demo video — as clean structured columns, one row per URL. No LLM cost, fully deterministic and reproducible.

Who it's for: GTM / sales-ops teams building tool directories, product researchers, VCs mapping software categories, and content teams writing tool round-ups.

Legal: it only visits the tool's own public marketing website — no login, no gated data.


Input

FieldTypeRequiredDefaultDescription
startUrlsarray of { url }The GTM tool website URLs to scrape. One output item per URL.
summaryMaxWordsinteger500Hard cap on summary length (min 20, max 2000). The summary is truncated on a word boundary to stay strictly under this number.
maxRequestsPerCrawlinteger100Safety cap on total requests to prevent runaway crawls.

Example input

{
"startUrls": [
{ "url": "https://www.clay.com/" }
],
"summaryMaxWords": 500,
"maxRequestsPerCrawl": 100
}

Output

One dataset item per input URL. Every value is a string.

FieldDescription
urlThe URL that was scraped (resolved loadedUrl).
tool_nameCompany/tool name.
summaryPlain-text "what it does" summary, under summaryMaxWords words.
demo_video_urlFirst demo/product video URL, or "" if none.
demo_video_sourceyoutube | vimeo | wistia | loom | html5 | link | none.
scraped_atISO-8601 UTC timestamp.

Example output

{
"url": "https://www.clay.com/",
"tool_name": "Clay",
"summary": "Infrastructure to get any data, run agentic workflows, and launch GTM plays. Build systems to grow revenue ...",
"demo_video_url": "",
"demo_video_source": "none",
"scraped_at": "2026-07-16T12:00:00.000Z"
}

On clay.com the hero video is a decorative background loop (autoplay loop muted), which is intentionally excluded from demo detection, and /demo is a gated "book a demo" form with no embedded player — so demo_video_source is correctly none.


How extraction works

Tool name (first non-empty wins)

  1. og:site_name
  2. og:title (split on |, -, , : — keep the brand segment)
  3. <title> (same cleaning)
  4. header/nav logo img[alt]
  5. capitalized registrable domain (e.g. clay.comClay)

Summary (deterministic extract-and-truncate — no LLM)

Candidate text is assembled in priority order — meta description → og:description → hero <h1> → hero subhead → first substantive <main> paragraphs → feature heading/description blocks — then whitespace-normalized, deduped, and truncated on a word boundary to strictly under summaryMaxWords. Nav, footer, cookie/consent and legal boilerplate are filtered out.

Demo video (first-match priority)

  1. YouTube embeds / youtu.be / lite-youtube facades → youtube
  2. Vimeo player iframes → vimeo
  3. Wistia embeds → wistia
  4. Loom embed/share links → loom
  5. Genuine <video> mp4 — decorative background loops excluded (autoplay + loop/muted, or video-bg/hero-video/bg-video classes) → html5
  6. Anchor last resort (/demo, /watch, /video, /product-tour, or "watch demo" / "see it in action" / "product tour" link text) → link
  7. Nothing → "" + none

All video URLs are resolved to absolute URLs.


Edge cases handled

  • Client-side SPAs (rendered with Playwright before extraction)
  • Decorative background <video> loops excluded from demo detection
  • Demos gated behind a "book a demo" form → none
  • Missing meta tags → priority-chain fallbacks, domain fallback for the name
  • Title padded with taglines/separators → brand segment kept
  • Cookie banners / nav / footer legal text filtered out of the summary
  • Very long pages → word-boundary truncation under the cap
  • Redirects (http→https, www, trailing slash) → original input URL recorded, resolved page scraped
  • Timeouts / 4xx-5xx → retried, then a best-effort row is still emitted (never lose a URL)
  • Relative / protocol-relative video hrefs → resolved to absolute
  • Duplicate input URLs → deduped to one item each

Notes

  • Uses Apify Proxy automatically to avoid IP blocks and geo-redirects across many domains.
  • Memory: ~2 GB recommended (headless Chromium).
  • Anti-detection/stealth is not needed — these are public marketing sites with no bot-hostile gating.