Scrapers

Pitchbook profiles

Bulk harvester for Pitchbook's roughly one million public profiles. Walks pitchbook.com/sitemap.xml down to the sub-sitemaps under public-profiles/, then optionally scrapes each profile page for the structured company or investor fields.

Updated today

Overview

At a glance
Worker
ultron-pitchbook-public-profiles
Runtime
Python, anti-fingerprint Firefox engine
Total addressable
~1M public profiles from the sitemap
Default discover cap
200 URLs (raise for production)
Kind filter
both | company | investor
Proxy
Residential US recommended
Default delay
1500 ms, +50% jitter

Fundraising-adjacent workflows need investor and portfolio metadata at scale. The Pitchbook public-profile surface is the broadest free source of normalised company + investor data; this actor turns it into structured rows we can land in the brain.

Three modes

ModeWhat it does
discoverWalks sitemap.xml + sub-sitemaps. Pushes URL discovery rows. No profile pages fetched.
scrapeTakes profileUrls[] from input. Fetches each profile, pushes parsed rows. No sitemap walk.
discover-and-scrapeDefault. Walks sitemap up to maxDiscoverUrls, then scrapes each. Combine input profileUrls[] with the discovered set.

Input schema

.actor/INPUT_SCHEMA.jsonjson
1{
2 "mode": "discover-and-scrape",
3 "profileUrls": [
4 "https://pitchbook.com/profiles/company/12345-67",
5 "https://pitchbook.com/profiles/investor/98765-43"
6 ],
7 "maxDiscoverUrls": 200, // 1 to 50000
8 "kindFilter": "both", // both | company | investor
9 "proxyConfiguration": {
10 "useApifyProxy": true,
11 "apifyProxyGroups": ["RESIDENTIAL"],
12 "apifyProxyCountry": "US"
13 },
14 "requestDelayMs": 1500,
15 "headless": true
16}

Crawl flow

src/__main__.pypy
1# Discovery phase (when mode in {discover, discover-and-scrape}):
2# 1. Fetch https://pitchbook.com/sitemap.xml. Extract sub-sitemap URLs
3# that contain /public-profiles/.
4# 2. Walk each sub-sitemap. Each entry contains a URL like
5# pitchbook.com/profiles/<kind>/<pbSlug>.
6# 3. Filter by kindFilter. Cap at maxDiscoverUrls. Push as kind="discovery".
7#
8# Scrape phase (when mode in {scrape, discover-and-scrape}):
9# 4. For each URL (input.profileUrls + discovered):
10# a. Open profile page in anti-fingerprint browser.
11# b. Parse hero block: name, kind, industry, founded, status, hqLocation.
12# c. Parse summary block for description + tags.
13# d. Push as kind="company" or kind="investor".
14# 5. Sleep requestDelayMs + 50% jitter between page loads.

Output shape

dataset-row.jsonjson
1// kind === "discovery"
2{
3 "kind": "discovery",
4 "pbSlug": "12345-67",
5 "url": "https://pitchbook.com/profiles/company/12345-67",
6 "kindGuess": "company"
7}
8
9// kind === "company"
10{
11 "kind": "company",
12 "pbSlug": "12345-67",
13 "name": "Linear",
14 "industry": "Application Software",
15 "founded": "2019",
16 "status": "Private",
17 "hqLocation": "San Francisco, California, US",
18 "description": "Linear builds tools for software engineering teams...",
19 "tags": ["Project Management", "B2B SaaS"],
20 "scrapedAt": "2026-05-19T12:00:00Z"
21}
22
23// kind === "investor"
24{
25 "kind": "investor",
26 "pbSlug": "98765-43",
27 "name": "Sequoia Capital",
28 "investorType": "Venture Capital",
29 "hqLocation": "Menlo Park, California, US",
30 "description": "...",
31 "scrapedAt": "2026-05-19T12:00:00Z"
32}

Anti-bot strategy

Cloudflare's JS challenge is the primary defense.

DefenseCounter
Cloudflare JS challengeAnti-fingerprint Firefox engine clears it without solving the puzzle (real DOM execution).
Datacenter IP gatingResidential US proxy.
Rate-limit per IP1500 ms minimum, jitter prevents pattern detection.
Hot-cache poisoning on heavy-hit profilesPer-URL retry budget is 1; we move on rather than hammer.

Webhook contract

actor.jsonjson
1{
2 "eventTypes": ["ACTOR.RUN.SUCCEEDED", "ACTOR.RUN.FAILED", "ACTOR.RUN.TIMED_OUT", "ACTOR.RUN.ABORTED"],
3 "requestUrl": "https://scraper-webhook.51ultron.com/apify",
4 "payload": { "actorName": "pitchbook-public-profiles", "source": "pitchbook", "datasetId": "<id>" }
5}

File map

actors/pitchbook-public-profiles
.actor
actor.json
INPUT_SCHEMA.json
src
__main__.py
Dockerfile
requirements.txt
README.md