The Mine Works
LinkedIn Profile Scraper: Experience, Education, and Skills Without Login
← All posts
tutorial June 23, 2026 · 2 min read

LinkedIn Profile Scraper: Experience, Education, and Skills Without Login

Extract full LinkedIn profile data — work history, education, skills, connections — from a list of profile URLs. No LinkedIn cookies or login required.

Try the scraper

The actor referenced in this article. Pay only for results delivered.

View the scraper →

LinkedIn blocks most scraping attempts with aggressive login walls and bot detection. The public profile pages — the ones visible when you open LinkedIn in an incognito window — are a different story. Our LinkedIn Profile Scraper targets only the unauthenticated public view, using residential proxies to load what any anonymous visitor can see.

What you get per profile

Each scraped record returns:

  • name — full name
  • headline — professional headline
  • location — location string
  • about — about section text
  • experience — array of {title, company, duration, description}
  • education — array of {school, degree, field, dates}
  • skills — array of skill label strings
  • connections — connection count string ("500+")
  • followers — follower count when visible
  • profile_url — canonical LinkedIn URL
  • scraped_at — ISO timestamp

Python example

import requests, time

run = requests.post(
    "https://api.apify.com/v2/acts/themineworks~linkedin-profile-scraper/runs",
    headers={"Authorization": f"Bearer {APIFY_TOKEN}"},
    json={
        "profileUrls": [
            "https://www.linkedin.com/in/satyanadella",
            "https://www.linkedin.com/in/jeffweiner08"
        ],
        "maxResults": 50
    }
)

run_id = run.json()["data"]["id"]

while True:
    status = requests.get(
        f"https://api.apify.com/v2/actor-runs/{run_id}",
        headers={"Authorization": f"Bearer {APIFY_TOKEN}"}
    ).json()["data"]["status"]
    if status in ("SUCCEEDED", "FAILED"):
        break
    time.sleep(5)

profiles = requests.get(
    f"https://api.apify.com/v2/actor-runs/{run_id}/dataset/items",
    headers={"Authorization": f"Bearer {APIFY_TOKEN}"}
).json()

for p in profiles:
    print(p["name"], p["headline"])
    for job in p.get("experience", []):
        print(f"  {job['title']} @ {job['company']}")

Load experience into a dataframe

import pandas as pd

records = []
for p in profiles:
    for job in p.get("experience", []):
        records.append({
            "person": p["name"],
            "profile_url": p["profile_url"],
            "title": job["title"],
            "company": job["company"],
            "duration": job.get("duration", ""),
        })

df = pd.DataFrame(records)
print(df.groupby("company").size().sort_values(ascending=False).head(20))

Private profiles

LinkedIn profiles that require login to view return a redirect to the login page. The actor detects this, logs a warning, skips the profile, and does not charge for it. The remaining profiles in the batch continue normally.

Handling 500+ connection counts

LinkedIn shows "500+" rather than an exact number for accounts above 500 connections. The connections field returns that string as-is. For filtering, treat any "500+" value as a minimum threshold.

Use cases

Sales prospecting. Enrich a list of LinkedIn URLs with job titles, companies, and career histories before passing leads to your CRM or outreach sequence.

Talent research. Map a candidate’s full work history and education without requiring a Recruiter license.

Competitive intelligence. Track leadership changes at target companies by scraping their executives’ profiles periodically.

Investor due diligence. Verify founder backgrounds, academic credentials, and prior companies in bulk before a meeting.

Pricing

$0.004 per profile. Private or inaccessible profiles are not charged.

Available on Apify.

Related Actor

Explore the scraper referenced in this article — see inputs, outputs, and pricing, then run it on Apify.