DEV Community

Devil Scrapes
Devil Scrapes

Posted on • Originally published at apify.com

Clutch Agency Leads Scraper: Service Mix + Verification Tier, No Extra Requests

Building a Clutch agency leads list by hand means paging through star ratings without ever seeing the two fields that actually predict fit: service mix and verification tier. Nobody scrolls that far, so nobody uses them — even though Clutch already ships both on every listing page.

(Suggested hero image: Devil Scrapes icon beside a cropped screenshot of the Apify Console output table with the service_mix and verification_tier columns visible.)

Clutch.co is the directory sales teams, procurement analysts, and RevOps stacks all lean on when they need to shortlist digital agencies or software vendors — filtered by category, by location, by whatever combination of "digital marketing agencies in Austin" you're chasing this quarter. Clutch publishes its own research methodology for how ratings and verification badges get assigned, which is exactly why those two fields are worth pulling in bulk rather than eyeballing one profile at a time. The listing pages are public. The problem isn't access; it's that turning 40 listing cards into a usable spreadsheet, by hand, for every category you care about, doesn't scale past a handful of searches before someone on the team starts asking for a tool — and that shortlisting step is a real, named stage in most B2B buying processes, not just a sales-team nicety.

What the data looks like

One row per agency, straight out of the listing page's own HTML — no profile-page crawl required:

{
  "clutch_provider_id": "1005123",
  "name": "Ninja Promo",
  "profile_url": "https://clutch.co/profile/ninja-promo",
  "category": "digital-marketing",
  "location_searched": "new-york",
  "city": "New York",
  "region": "NY",
  "country": "United States",
  "employee_band": "250 - 999",
  "hourly_rate_band": "$50 - $99 / hr",
  "min_project_size": "$5,000+",
  "rating": 4.9,
  "review_count": 95,
  "verification_tier": "premier",
  "service_mix": [
    { "service_name": "Advertising", "percent": 10 },
    { "service_name": "Fractional CMO Services", "percent": 5 }
  ],
  "listing_type": "organic",
  "phone": "+1 212 555 0100",
  "position": 3,
  "scraped_at": "2026-07-30T12:00:00Z"
}
Enter fullscreen mode Exit fullscreen mode

verification_tier is Clutch's own premier / basic / none trust signal, surfaced as a real, filterable field instead of a badge icon you'd have to eyeball. service_mix is the array most Clutch scrapers on the Apify Store don't bother extracting — a percentage breakdown of what the agency actually does (SEO vs. PPC vs. content vs. dev), parsed out of the same listing card that already carries the rating and rate band. Zero extra requests to get it; it's sitting in the DOM the whole time.

The naive approach, and why it stalls

Open devtools on a Clutch category page and the instinct is reasonable: grab the listing cards with a quick requests.get() + BeautifulSoup pass, loop the pagination, done by lunch. It works for about 20 rows.

Then the requests start coming back with a challenge page instead of listing HTML, because a plain Python requests session has a TLS fingerprint that doesn't look like a browser — no realistic cipher suite order, no matching HTTP/2 SETTINGS frame, nothing a modern anti-bot layer needs to see twice before it stops trusting you. Retry naively and you get rate-limited instead of blocked outright, which is worse: your script looks like it's working while it's actually returning stale or partial pages. And the service-mix percentages live inside a tooltip/chart widget with its own nested markup, not a clean <td> — miss the parsing edge case and you silently drop the one field that made the scrape worth doing.

None of that is exotic. It's just the standard tax every directory-scraping project pays, and it's exactly the tax we've already paid so you don't have to.

The Actor

We rotate real browser TLS fingerprints — Chrome, Firefox, Safari impersonation via curl-cffi — so Clutch's listing pages see a browser, not a bare Python client. We retry on 408 / 429 / 5xx with exponential backoff (capped at 5 attempts, Retry-After honoured), and if Clutch pushes back, we pace down instead of hammering until we get banned outright. Every row gets validated against a Pydantic schema before it lands in your dataset — no half-parsed service-mix arrays, no silent nulls where a rate band should be. The Actor runs on Apify's platform, so the same run also gives you scheduling, dataset export (JSON/CSV/Excel), and API access without any of that being code you have to write yourself.

Run it with a category slug and, optionally, a location slug:

{
  "category": "digital-marketing",
  "location": "new-york",
  "maxResults": 200,
  "maxPages": 10,
  "proxyConfiguration": { "useApifyProxy": false }
}
Enter fullscreen mode Exit fullscreen mode

(Suggested screenshot: the Apify Console run page mid-run, showing the dataset item counter climbing, or the finished Storage → Dataset table with service_mix and verification_tier columns visible.)

Or call it from Python via the Apify Client SDK:

from apify_client import ApifyClient

client = ApifyClient("APIFY_TOKEN")
run = client.actor("DevilScrapes/clutch-agency-leads-scraper").call(
    run_input={"category": "digital-marketing", "location": "new-york", "maxResults": 200}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["name"], item["verification_tier"], item["service_mix"])
Enter fullscreen mode Exit fullscreen mode

Proxy is optional here — Clutch's listing pages currently clear on browser-impersonation alone, live-confirmed. If you start seeing blocks on a heavy pull, flip on a residential proxy group in the same input object; we handle the session rotation from there.

What you'd actually use this for

  • Call-list building — pull every agency in a category + city, filter by verification_tier and rating before an SDR ever picks up the phone.
  • RFP shortlisting — turn a category listing page into a comparable spreadsheet (rate band, minimum project size, employee band) instead of 40 open browser tabs.
  • Positioning research — track service_mix across a category over time to see how agencies are repositioning (more content, less pure SEO, that kind of shift).
  • Lead scoring input — feed verification tier + rating + service mix into whatever scoring model your RevOps stack already runs, ahead of a human touch.

One thing this Actor is not: an email-enrichment tool. Several other Clutch scrapers on the Apify Store lead with verified-email extraction pulled from each agency's own site — that's a real, useful feature, and it's genuinely not what this one does. If you need Clutch's structured directory data — ratings, verification tier, rate bands, and the service-mix breakdown specifically — cheaply and fast, and you already have (or don't yet need) your own enrichment step, that's the gap this Actor fills. Say it plainly now so nobody's surprised later.

Pricing

Pay-Per-Event, no subscription:

Event Price
actor-start $0.02 (one-off, per run)
result-scraped $0.0018 (per unique dataset item)

1,000 results ≈ $1.82 all-in. No card required to try — every new Apify account gets $5 of free credit, which covers roughly 2,700 leads on this Actor.

Why the service-mix field is the interesting part

Everything else on a Clutch listing card is a value you copy-paste. service_mix is the one field that's structurally a chart — Clutch renders it as a stacked bar with hover-triggered tooltips, which is a UI pattern built for a human eyeballing one card at a time, not for bulk extraction. The percentages are attached to the underlying markup regardless of whether the tooltip ever fires, so we read them straight from the DOM instead of trying to trigger and scrape a hover state. It's the difference between fighting the page's interaction model and just reading its data model — a distinction every scraper eventually has to make peace with, on Clutch or anywhere else.

Limitations, honestly

This Actor reads category/location listing pages only — no profile-page detail (reviews, portfolio, case studies, team bios), and, again, no email extraction or enrichment. One category slug per run; if you need ten categories, orchestrate ten runs from your side (or a scheduled batch). If a category or location slug doesn't exist, the run finishes cleanly with zero rows and a warning in the log — it doesn't fail loud for a typo, but it also won't return fabricated rows to mask one.

Try it

Live on the Apify Store: https://apify.com/DevilScrapes/clutch-agency-leads-scraper. Every new Apify account starts with $5 of free credit — no card needed to run your first category pull and see the service-mix field for yourself.

If you're already running a different Clutch scraper and just need those two fields without re-plumbing your pipeline, that's the whole pitch. What would you want in the dataset next — profile-page detail, historical rating tracking, something else? Drop it in the comments; we ship new fields based on what people actually ask for.

Top comments (0)