Scrape LinkedIn profiles and search results using the user's authenticated Chrome browser session. No API keys needed — uses the browser tool with the Chrome profile relay.
text
browser → open LinkedIn profile URL
browser → snapshot (extract structured data)
→ Parse: name, headline, title, company, location, education, experience, connections, about
→ Return structured JSON or insert into DuckDB
text
browser → open LinkedIn search URL with filters
browser → snapshot (extract result cards)
→ Parse each result: name, title, company, profile URL
→ For each profile URL: open → snapshot → parse full profile
→ Batch insert into DuckDB
text
browser → open LinkedIn company page
→ Parse: company name, industry, size, description, specialties, employee count
→ Navigate to /people tab for employee list
From a LinkedIn profile snapshot, extract these fields:
FieldLocationNotesnameMain heading h1Full nameheadlineBelow nameTitle + Company usuallylocationLocation sectionCity, State/Countrycurrent_titleExperience section, first entryMost recent rolecurrent_companyExperience section, first entryCompany nameeducationEducation sectionSchool, degree, datesconnectionsConnections countNumber or "500+"aboutAbout sectionBio text (may need "see more" click)experienceExperience sectionAll roles with datesprofile_urlBrowser URL barCanonical LinkedIn URL
From LinkedIn search results page:
FieldLocationnameResult card headingheadlineBelow name in cardlocationCard metadataprofile_urlLink href on namemutual_connectionsCard footer
text
# People search
https://www.linkedin.com/search/results/people/?keywords={query}
# With filters
&geoUrn=%5B%22103644278%22%5D # United States
&network=%5B%22F%22%2C%22S%22%5D # 1st + 2nd connections
¤tCompany=%5B%22{company_id}%22%5D # Current company
&schoolFilter=%5B%22{school_id}%22%5D # School filter
# YC founders (common query)
https://www.linkedin.com/search/results/people/?keywords=Y%20Combinator%20founder
# Company employees
https://www.linkedin.com/company/{slug}/people/
When storing to DuckDB, use the Ironclaw workspace database:
sql
-- Check if leads/contacts object exists
SELECT * FROM objects WHERE name = 'leads' OR name = 'contacts';
-- Insert via the EAV pattern or direct pivot view
INSERT INTO v_leads ("Name", "Title", "Company", "LinkedIn URL", "Location", "Source")
VALUES (?, ?, ?, ?, ?, 'LinkedIn Scrape');
If no suitable object exists, create one:
sql
-- Use Ironclaw's object creation pattern from the dench skill
ErrorAction"Sign in" pageLinkedIn session expired — alert user to re-login in ChromeCAPTCHA / Security checkStop immediately, wait 30+ min, alert user"Profile not found"Skip, log URL as invalidRate limit (429)Stop, wait 15 min, retry with longer delaysEmpty snapshotPage still loading — wait 3s and re-snapshot
json
{
"name": "Jane Doe",
"headline": "CEO at Acme Corp",
"current_title": "CEO",
"current_company": "Acme Corp",
"location": "San Francisco, CA",
"linkedin_url": "https://www.linkedin.com/in/janedoe",
"connections": "500+",
"education": [{"school": "Stanford", "degree": "BS CS", "years": "2010-2014"}],
"experience": [{"title": "CEO", "company": "Acme Corp", "duration": "2020-Present"}],
"scraped_at": "2026-02-17T14:30:00Z"
}
For bulk scrapes, report progress:
text
Scraping: 15/50 profiles (30%) — Last: Jane Doe (Acme Corp)
Rate: ~4 profiles/min — ETA: 9 min remaining