with one click
linkedin-profile-scraper
// Scrape LinkedIn profile data (name, current company, country, work history, industry) filtered by company, country, and industry. Uses Playwright MCP browser automation.
// Scrape LinkedIn profile data (name, current company, country, work history, industry) filtered by company, country, and industry. Uses Playwright MCP browser automation.
Three LinkedIn automation skills โ (1) auto-apply to Easy Apply jobs, (2) scrape profile data by company/country/industry, (3) discover contacts via BFS/DFS for referrals/networking with email generation. Uses Playwright MCP browser automation.
Systematically discover LinkedIn contacts for job referrals or networking using BFS/DFS traversal. Extracts LinkedIn URLs, generates company email candidates, optionally sends connection requests, and saves output locally as JSON + CSV.
Automate job applications on LinkedIn using Playwright MCP tools. Features Easy Apply support, target-based stopping, keyboard controls (P/R/Q), on-page status indicator, and proven automation patterns.
Email address generation and validation specialist. Generates probable work and personal email candidates from name + company domain, infers company domains, prioritises patterns by industry, and advises on verification.
Contact discovery specialist. Designs BFS/DFS traversal strategies, selects optimal seeds, tunes depth/breadth trade-offs, and handles LinkedIn's social graph structure for systematic contact finding.
Connection request and outreach specialist. Crafts personalized message templates, enforces LinkedIn rate limits, advises on referral vs networking tone, and maximises acceptance rates.
| name | linkedin-profile-scraper |
| description | Scrape LinkedIn profile data (name, current company, country, work history, industry) filtered by company, country, and industry. Uses Playwright MCP browser automation. |
Search LinkedIn people by company, country, and/or industry, then extract structured profile data for each result.
This skill is backed by three specialist agents. Invoke them for deeper help:
| Agent | File | When to Use |
|---|---|---|
| Automation Agent | skills/agents/automation-agent/SKILL.md | Timing strategy, retry logic, rate limiting |
| Web Structure Agent | skills/agents/web-structure-agent/SKILL.md | Broken selectors, missing fields, lazy load fixes |
| QA Agent | skills/agents/qa-agent/SKILL.md | Validate scraped data, completeness reports |
1. QA Agent โ preFlightCheck(page) # must PASS โ abort if it fails
2. [run batch scrape]
3. QA Agent โ validateBatchResults() # completeness scoring
4. QA Agent โ generateReport() # PASS/WARN/FAIL summary
Escalation:
The scraper builds a keyword query by joining company + country + industry as plain text. LinkedIn's people search does not parse this as structured filters โ it treats everything as keywords.
For structured filtering (e.g., company by URN, geo by URN), LinkedIn's search API requires internal IDs not exposed in the UI. The most reliable workaround is to:
facetCurrentCompany, facetGeoRegion, etc.)Ask the Web Structure Agent for current URN lookup patterns if you need fully structured URL construction.
| Field | Description |
|---|---|
name | Full name |
headline | Professional headline |
location | Current country / city |
currentCompany | Most recent employer |
currentTitle | Current job title |
industry | Industry label |
workHistory | Array of { title, company, dateRange, location } |
profileUrl | LinkedIn profile URL |
scrapeLinkedInProfiles.js โ batch scraper: searches by filters, visits each profile, returns array of profilesscrapeSingleProfile.js โ scrape one profile by URL// Paste scrapeSingleProfile.js first, then:
const profile = await scrapeSingleProfile(page, 'https://www.linkedin.com/in/username/');
console.log(JSON.stringify(profile, null, 2));
// Paste scrapeLinkedInProfiles.js first, then:
// Example 1: engineers at Google in the US
const results = await scrapeLinkedInProfiles(page, {
company: 'Google',
country: 'United States',
industry: 'Software Development',
maxProfiles: 20
});
// Example 2: finance professionals in Singapore
const results = await scrapeLinkedInProfiles(page, {
industry: 'Financial Services',
country: 'Singapore',
maxProfiles: 15
});
// Example 3: keyword search
const results = await scrapeLinkedInProfiles(page, {
keywords: 'machine learning',
company: 'OpenAI',
maxProfiles: 10
});
console.log(JSON.stringify(results, null, 2));
| Option | Default | Description |
|---|---|---|
company | '' | Target company name |
country | '' | Target country |
industry | '' | Target industry |
keywords | '' | Additional search keywords |
maxProfiles | 10 | Max profiles to scrape |
maxPages | 5 | Max search result pages to scan |
delayMin | 2000 | Min delay between requests (ms) |
delayMax | 4000 | Max delay between requests (ms) |
[
{
"status": "success",
"name": "Jane Smith",
"headline": "Senior Software Engineer at Google",
"location": "San Francisco, California",
"currentCompany": "Google",
"currentTitle": "Senior Software Engineer",
"industry": "Software Development",
"workHistory": [
{
"title": "Senior Software Engineer",
"company": "Google",
"dateRange": "Jan 2021 โ Present ยท 3 yrs",
"location": "San Francisco, CA"
},
{
"title": "Software Engineer",
"company": "Meta",
"dateRange": "Jun 2018 โ Dec 2020 ยท 2 yrs 6 mos",
"location": "Menlo Park, CA"
}
],
"profileUrl": "https://www.linkedin.com/in/janesmith/"
}
]
const p = await scrapeSingleProfile(page, 'https://www.linkedin.com/in/satyanadella/');
console.log(p.name, p.currentCompany, p.location);
copy(JSON.stringify(results, null, 2)); // copies to clipboard in browser console
maxProfiles โค 50 per sessionEmpty workHistory: LinkedIn lazy-loads experience sections. The script scrolls to trigger them, but if the page is slow, increase delayMin to 3000.
name is null: LinkedIn may show a login wall. Ensure you are logged in before running.
No profiles found in search: Try broader keywords or remove some filters. LinkedIn search ranking can be unpredictable.