How to scrape LinkedIn
Scrape LinkedIn public company and job pages into typed JSON with Extracto. Profile and feed data is login-gated and Enterprise-only.
- Site:
- linkedin.com
- Difficulty:
- Hard
- Rendering:
- Single-page app
- Anti-bot:
- heavy fingerprinting and behavioral analysis, Cloudflare-class managed challenges, aggressive rate limiting and 999 throttle responses, authwall redirects to login on most member-facing URLs
What you can extract from LinkedIn
These are the fields teams most often pull from linkedin.com, and why a hand-written selector for each one tends to break over time.
| Field | Type | Why selectors break |
|---|---|---|
| companyName | string | LinkedIn renders the company page as a single-page app with React-style hashed class names like artdeco-entity-lockup__title that change between deploys, and the visible name often sits behind an authwall variant served to logged-out visitors, so a fixed h1 selector silently returns the login prompt text instead. |
| followerCount | number | The follower count is injected client-side after hydration and formatted with locale-specific abbreviations such as 12K followers or 1.2M, so a CSS selector grabs a non-numeric string that breaks on every locale and shows nothing until the SPA JavaScript has executed in a real browser. |
| employeeCount | number | LinkedIn shows employee counts as a fuzzy range link like 51-200 employees on LinkedIn rather than a clean integer, and the anchor it lives in is reused for the headcount, the see all employees link, and the associated-members module, so a selector cannot tell which number it captured. |
| industry | string | Industry is rendered inside an unlabeled dot-separated metadata line that also contains headquarters location and company size, with no stable data attribute distinguishing the three, so a positional CSS selector breaks the moment LinkedIn reorders or omits one of those fragments for a given company. |
| jobTitle | string | On job postings the title element shares generic top-card classes with the company name and apply button, and LinkedIn frequently A/B tests the job detail layout, so a selector tuned to one variant returns an empty value or the wrong node for visitors served the alternate template. |
The schema-first approach
Instead of maintaining selectors, you hand Extracto a JSON schema describing the shape you want. Here is a schema that works for LinkedIn:
{
"companyName": "string",
"tagline": "string",
"industry": "string",
"headquarters": "string",
"companySize": "string",
"employeeCount": "number",
"followerCount": "number",
"founded": "number",
"website": "string",
"specialties": "string",
"about": "string"
} - 1
Describe the LinkedIn fields you want
Write a small JSON schema listing the fields to pull from linkedin.com (for example companyName, followerCount, employeeCount). No CSS selectors or XPath needed.
- 2
Send the URL and schema to Extracto
POST the LinkedIn page URL and your schema to the Extracto API. Extracto renders the page in a real browser, handling JavaScript and dynamic content automatically.
- 3
Get schema-validated JSON back
Extracto returns JSON that matches your schema exactly, validated before it leaves the API, so your pipeline never receives broken or partial data.
Common pitfalls when scraping LinkedIn
- The single biggest mistake is aiming at profile, feed, or connection data. Personal profiles, the home feed, search results and messaging are login-gated behind LinkedIn's authwall, so they require session cookies and are out of scope for standard scraping. With Extracto, cookie-authenticated reads are an Enterprise-only capability, and even then you must have a lawful basis and respect the User Agreement.
- Logged-out company URLs often redirect to a login or signup interstitial that returns HTTP 200 with real HTML, so a naive scraper records the authwall as a successful page. Always validate that the typed fields are populated and treat an all-null result as a likely authwall, not as a company with no data.
- LinkedIn returns a 999 status code and aggressive rate limiting when it sees automated traffic patterns. Firing many requests in a short window from the same path will get throttled fast, so keep volume modest, one URL per call, and space requests out rather than crawling the org's full employee list.
- Follower and employee figures are abbreviated and localized (12K, 1,2 M depending on locale), so do not assume the captured string is a parseable integer. Extracto's schema typing coerces and validates these, returning null when a value cannot be trusted rather than emitting a guessed number.
- Treating LinkedIn like a crawler is both a technical and a legal trap. Extracto reads one public URL per call by design and does not walk the connection graph, which keeps you on the safer side of the Crawling Terms. Do not chain it into a graph traversal of profiles.
Is it legal to scrape LinkedIn?
LinkedIn is one of the most legally contested scraping targets on the web, so treat it with extra care. The LinkedIn User Agreement explicitly prohibits using "software, devices, scripts, robots, or any other means or processes to scrape the Services or otherwise copy profiles and other data," and the separate Crawling Terms require express written permission for automated crawling and indexing. LinkedIn's robots.txt disallows most member and search paths while permitting a narrow set of public surfaces, and you must respect it on every request. The hiQ v. LinkedIn litigation established that scraping data already public can avoid CFAA liability in some US contexts, but it did not bless breach of contract, and LinkedIn has continued to pursue and ban scrapers. Practical guidance: only read genuinely public company and job pages, never log in to reach gated profiles, never harvest personal data of individuals (names, contact details, employment history) without a lawful basis under GDPR and similar laws, keep volume modest, and consider LinkedIn's official Marketing and Talent APIs for member data. When in doubt, do not collect it.
Extracto follows robots.txt by default and rate-limits politely. You are responsible for compliance with LinkedIn's terms and applicable law (GDPR, CCPA) in your use case.