Start free

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. 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. 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. 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

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.

Scraping LinkedIn: FAQ

Can Extracto scrape LinkedIn personal profiles?
Not on standard plans. Individual member profiles, the feed, search and messaging sit behind LinkedIn's authwall and require an authenticated session cookie to load. Extracto only fetches public HTTPS URLs by default, so logged-out profile requests return the login interstitial rather than profile data. Cookie-authenticated reads are an Enterprise-only capability, and even then you must have a lawful basis under GDPR and comply with LinkedIn's User Agreement, which broadly prohibits scraping member data.
What LinkedIn data can I actually extract without logging in?
Public company pages and many public job postings render useful structured fields to logged-out visitors, including company name, tagline, industry, headquarters, company size, follower count, founding year, website, specialties and the about text. Job pages expose title, company, location and the description. These are the surfaces Extracto can read through its managed rendering and anti-bot layer. Profile-level and feed data is not available this way because it is gated behind login.
Is scraping LinkedIn legal?
It is contested and depends heavily on what you collect and how. The hiQ v. LinkedIn case suggested that accessing already-public data may avoid US Computer Fraud and Abuse Act liability in some situations, but it did not override LinkedIn's User Agreement, which prohibits automated scraping. Reading genuinely public company and job pages at modest volume while respecting robots.txt is the defensible end; harvesting personal data of individuals is not. Read the legal note above and consult your own counsel before collecting anything.
How does Extracto handle LinkedIn's anti-bot challenges?
Every Extracto request runs the page through a real headless browser with a managed anti-bot layer and managed proxies, so JavaScript-rendered company pages hydrate the way they would for a normal visitor before fields are read. You do not configure proxies or browser settings. This is framed as managed rendering infrastructure, not evasion. You should still keep request volume modest and respect LinkedIn's rate limits, since heavy automated traffic triggers 999 responses regardless of rendering quality.
Why use a JSON schema instead of CSS selectors for LinkedIn?
LinkedIn is a single-page app with hashed, frequently rotated class names and A/B-tested layouts, so CSS selectors break constantly and silently. With Extracto you send a flat JSON schema describing the fields you want, and you get back typed JSON validated against it, with any field it cannot find returned as null instead of a guessed value. That means a layout change degrades to a null field you can detect, not a wrong number you trust by mistake.