LinkedIn Profile Posts Scraper With Lead Enrichment
Pricing
from $5.99 / 1,000 results
LinkedIn Profile Posts Scraper With Lead Enrichment
Scrape LinkedIn profile posts with lead enrichment data, including post content, timestamps, engagement, job titles, companies, locations, and profile URLs. Discover active prospects, analyze interests, enrich B2B leads, personalize outreach, and support sales and marketing campaigns.
Pricing
from $5.99 / 1,000 results
Rating
0.0
(0)
Developer
Scrapier
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
6 days ago
Last modified
Categories
Share
LinkedIn Profile Posts Scraper — Extract Posts and Engaged Leads
LinkedIn Profile Posts Scraper With Lead Enrichment pulls the public posts of any LinkedIn profile and returns them as structured JSON — the real post body, publish date, exact reaction and comment counts, and media — plus a lead row for every real person who commented, enriched from that commenter's own public profile. Every field in every row is read off a page the Actor actually fetched. No LinkedIn login, no AI guessing, no placeholder padding.
🧭 What is LinkedIn Profile Posts Scraper With Lead Enrichment?
It is an Apify Actor that takes a LinkedIn personal profile URL (/in/...) and runs a three-stage pipeline:
- Discover — it loads the public profile page and reads two things from it: the
PersonJSON-LD node (name, headline, current employer, location, education, follower count) and the list of that profile's own post permalinks. - Fetch — it opens every post permalink (
linkedin.com/posts/<slug>_…-activity-<id>-<code>). These pages are server-rendered for search engines, so they carry the untruncated post body, the publish timestamp, the exactdata-num-reactions/data-num-commentsvalues and up to ten real comments with their authors' profile links. - Enrich — each commenter is promoted into an
engagedLeadrow, and (optionally) their own profile page is fetched so the row can carry their real headline, employer and location.
- 🎯 Seniority & decision-maker classification on posts and leads, from a keyword rule set run against a scraped headline (CEO, Founder, Chairman, VP, Director, Head of, Manager…)
- 🤝 Engaged leads — every named commenter becomes its own linked row, with their comment text and its reaction count
- 🧭 Profile-sourced enrichment — a lead's employer/headline/location always comes from that lead's own profile page, never from the post text
- 🔎 Google top-up discovery — a profile page publicly lists only its most recent handful of posts; the Actor asks Google for older permalinks by the same author to reach your target
- 🔁 Address-rotating fetch layer — LinkedIn rate-limits per source address, so the Actor round-robins across a pool of Apify Proxy sessions and parks any address that gets throttled
- 📡 Live dataset output — rows are pushed as they are found, not batched at the end of the run
📊 What data can you get with LinkedIn Profile Posts Scraper With Lead Enrichment?
The Actor writes two row types into one flat dataset, distinguished by a type field: profile posts and promoted engaged leads.
| Result type | Extracted fields (top-level) | Primary use case |
|---|---|---|
post | urn, url, text, postedAtISO, numLikes, numComments, topReactionTypes, postType, image, images, videoUrl, articleUrl, authorFullName, authorHeadline, authorCompany, authorCompanyUrl, authorLocation, authorFollowers, authorAlumniOf, seniorityLevel, isDecisionMaker, commentsSampled | Track what a person is posting and how it actually performs |
engagedLead | parentId, url, text, commentLikes, postedAtISO, authorFullName, authorProfileUrl, authorProfileId, plus authorHeadline / authorCompany / authorLocation / seniorityLevel when their profile could be fetched | Build outreach lists from real people who engaged with a target's content |
Rows are not padded. If a value is not on the page — a post with no linked article, a lead whose profile page did not load — the key is simply absent from that row rather than present as null, 0 or "N/A".
🎯 Engaged leads
Every type: "engagedLead" row is one real, named person who commented on a scraped post. A comment is promoted only when the page yields both a display name and a real /in/ profile link; anything else is dropped rather than turned into a placeholder identity. The comment text and its reaction count come from the post page; the headline, employer and location come from a separate fetch of that commenter's own profile.
{"type": "engagedLead","isChild": true,"parentId": "urn:li:activity:7496695637644828672","urn": "urn:li:comment:(urn:li:ugcPost:7496695636868726785,7496700240079646720)","url": "https://www.linkedin.com/posts/satyanadella_delivery-day-at-our-microsoft-dcs-as-the-activity-7496695637644828672-K-l_","text": "AI may feel like software, but the race is increasingly about physical infrastructure…","commentLikes": 9,"postedAtISO": "2026-08-21T22:50:19.190000Z","timeSincePosted": "1w","authorFullName": "Svetlana I.","authorProfileUrl": "https://www.linkedin.com/in/svetlana-i-595b37233","authorProfileId": "svetlana-i-595b37233","scrapedAt": "2026-08-30T06:51:17.972622Z"}
🔐 What this Actor deliberately does not return
Logged out, LinkedIn publishes no email addresses and no phone numbers anywhere on a profile or post page — contact details sit behind an authenticated overlay. It also replaces a logged-out visitor's view of jobTitle and past employers with literal asterisks. So this Actor emits no email or phone field at all, and it filters redacted asterisk values out before writing a row. A scraper that hands you a LinkedIn email from a logged-out fetch either logged in or made it up.
🛠️ Why not build a LinkedIn post scraper yourself?
LinkedIn has no public, self-serve API for an arbitrary profile's posts — its developer platform is partner-gated. Doing it in-house means three separate problems. First, discovery: a profile page lists only a handful of recent permalinks, and the older ones have to come from somewhere else. Second, the block behaviour: logged-out /in/ pages answer an unwelcome source address with HTTP 999 and a 1.5 KB authwall stub, and roughly six requests in fifteen seconds from one address earns an HTTP 429 whose body is 24 KB of HTML — so a naive "did I get bytes back?" check parses a block page as if it were real content. Third, extraction: post text, engagement counts, author identity and comment identity all live in different parts of the same page, and the avatars sit right next to the post's own media. This Actor solves all three: profile-page enumeration plus Google top-up, an address-rotating fetch pool that parks throttled addresses and only ever accepts an explicit HTTP 200, and JSON-LD-first extraction with an attribution guard on every author field.
🚀 How to scrape LinkedIn profile posts with LinkedIn Profile Posts Scraper With Lead Enrichment
- Open the Actor's page in Apify Console under the Scrapier account, or search for linkedin-profile-posts-scraper-with-lead-enrichment in the Apify Store.
- Paste one or more LinkedIn profile URLs into the required
urlsfield (e.g.https://www.linkedin.com/in/satyanadella). - Set the controls you need:
maxPosts,minSeniorityLevel,includeEngagedLeads, and under ⚙️ Advanced SettingsenrichLeadProfiles,maxLeadProfileFetches,useGoogleDiscovery,rateLimitDelay,fetchRetries. - Click Start to run the Actor.
- Open the Output tab, filter by the
typecolumn to separate posts from engaged leads, or export the dataset as JSON, CSV, or another format the Apify dataset supports.
🔁 How to run multiple profiles in one job
urls is a list field — paste each profile URL on its own line and they all run in the same job. The Actor processes URLs one at a time inside a single run (there is no concurrency setting in the input schema); to scrape a large number of profiles faster, split the list across multiple scheduled runs rather than expecting parallel processing within one run.
⬇️ Input
| Parameter | Required | Type | Constraints | Description |
|---|---|---|---|---|
urls | Yes | array | editor: stringList | LinkedIn profile URLs to scrape (e.g. https://www.linkedin.com/in/username). Paste each URL on a new line. Only personal profile URLs (/in/...) are processed. |
maxPosts | No | integer | min 1, max 200, default 10 | Maximum posts to fetch per profile. Each post is a separate page fetch. |
includeEngagedLeads | No | boolean | default true | Promote every real, named commenter on a scraped post into its own engagedLead row, linked via parentId. |
minSeniorityLevel | No | string | enum: any, manager, director, vp, executive; default any | Keep only posts whose author's scraped headline classifies at or above this level. |
enrichLeadProfiles | No | boolean | default true | Fetch each commenter's own profile page to read their real headline, employer and location. |
maxLeadProfileFetches | No | integer | min 0, max 500, default 60 | Budget for those enrichment fetches per run. Leads past the budget still ship with name, profile URL and comment. |
useGoogleDiscovery | No | boolean | default true | Ask Google for additional post permalinks by the same author when the profile page lists fewer than maxPosts. |
rateLimitDelay | No | integer | min 0, max 30, default 1 | Base delay in seconds between requests. |
fetchRetries | No | integer | min 0, max 10, default 2 | Retry attempts per connection tier before falling through to the next one. |
proxyConfiguration | No | object | editor: proxy | Apify Proxy settings. Enabled by default — profile pages are unreachable from an unproxied address. |
Example input
{"urls": ["https://www.linkedin.com/in/satyanadella","https://www.linkedin.com/in/reidhoffman"],"maxPosts": 10,"includeEngagedLeads": true,"minSeniorityLevel": "any","enrichLeadProfiles": true,"maxLeadProfileFetches": 60,"useGoogleDiscovery": true,"rateLimitDelay": 1,"fetchRetries": 2,"proxyConfiguration": { "useApifyProxy": true }}
Common pitfalls
- Only
/in/profile URLs are accepted. Company pages, individual post URLs, feed URLs, school pages, and group URLs are skipped with a logged warning. - Leave Apify Proxy on. LinkedIn answers an unproxied request for a
/in/profile page with HTTP 999 and a 1.5 KB authwall stub; the run will find no profile and no posts. - A profile page publicly exposes only its most recent posts (typically 6–9). Asking for
maxPosts: 100does not fail, but the extra permalinks have to come fromuseGoogleDiscovery, and how many exist depends on what Google has indexed for that person. commentsSampledis how many comments the public page rendered (usually up to ten).numCommentsis the post's real total. They are different numbers on purpose — the Actor does not pretend to have every comment.- Lead enrichment is best-effort: some commenter profiles do not load on a given attempt, and some genuinely publish no headline. Those rows arrive without the enrichment keys instead of with empty ones.
⬆️ Output
Results are typed JSON rows written to the Actor's default dataset, exportable as JSON, CSV, Excel, HTML table, or the other formats Apify datasets support. Every row carries type, isChild, and (for leads) parentId so the two row kinds can be told apart and joined back together in one flat table.
📋 Scraped results
[{"type": "post","isChild": false,"urn": "urn:li:activity:7411490079984250880","url": "https://www.linkedin.com/posts/satyanadella_looking-ahead-to-2026-activity-7411490079984250880-Vb5v","text": "A few reflections on the year ahead for our industry ... https://lnkd.in/gwygrzzB","postedAtISO": "2025-12-29T19:35:33.873000Z","postedAtTimestamp": 1767036933873,"timeSincePosted": "8mo","numLikes": 4068,"numComments": 365,"topReactionTypes": ["LIKE", "INTEREST", "EMPATHY"],"postType": "image","image": "https://media.licdn.com/dms/image/sync/v2/D5627AQElyumqPbAGzw/articleshare-shrink_800/...","images": ["https://media.licdn.com/dms/image/sync/v2/D5627AQElyumqPbAGzw/articleshare-shrink_800/..."],"authorFullName": "Satya Nadella","authorProfileUrl": "https://www.linkedin.com/in/satyanadella","authorProfileId": "satyanadella","authorHeadline": "Chairman and CEO at Microsoft","authorCompany": "Microsoft","authorCompanyUrl": "https://www.linkedin.com/company/microsoft","authorLocation": "Redmond, Washington, United States","authorFollowers": 12139567,"authorAlumniOf": ["The University of Chicago Booth School of Business"],"authorImage": "https://media.licdn.com/dms/image/v2/C5603AQHHUuOSlRVA1w/profile-displayphoto-shrink_200_200/...","seniorityLevel": "Executive","isDecisionMaker": true,"commentsSampled": 10,"scrapedAt": "2026-08-30T06:52:28.508002Z"},{"type": "engagedLead","isChild": true,"parentId": "urn:li:activity:7411490079984250880","urn": "urn:li:comment:(urn:li:ugcPost:7411490079107645440,7411502882109034496)","url": "https://www.linkedin.com/posts/satyanadella_looking-ahead-to-2026-activity-7411490079984250880-Vb5v","text": "The shift from copilots to autonomous agents is the part most teams are underestimating.","commentLikes": 12,"postedAtISO": "2025-12-29T20:26:12.441000Z","timeSincePosted": "8mo","authorFullName": "Jyotsna (Jo) Dixit","authorProfileUrl": "https://www.linkedin.com/in/jodixit","authorProfileId": "jodixit","authorHeadline": "As a high-achieving tech professional, you've worked hard to get where you are…","authorCompany": "BricksFolios | Wealth-Tech for Tech Professionals","authorLocation": "Redmond, Washington, United States","seniorityLevel": "Individual Contributor","isDecisionMaker": false,"scrapedAt": "2026-08-30T06:52:31.114003Z"}]
Charged rows are pushed via the row_result event. A blocked or failed fetch produces a log warning and no dataset row at all, so it is never charged.
💼 How can I use the data extracted with LinkedIn Profile Posts Scraper With Lead Enrichment?
- 🎯 Sales / BDR teams: filter posts with
minSeniorityLevel: "director"or higher, then work the linkedengagedLeadrows on those posts as a warm-comment outreach list instead of a cold one. - 🏢 Account-based marketing teams: track a set of target-account executives'
urls, and useseniorityLevel/isDecisionMakerto confirm which of their posts are actually reaching decision-makers before running ad or outreach sequences against that content. - 🤖 AI engineers and LLM developers: feed the JSON rows directly into a grounded agent — the agent requests a profile's recent posts, receives typed fields like
text,authorHeadline, andnumLikes, and reasons over them as context instead of hallucinating engagement data. - 📊 Market and competitive researchers: compare posting cadence,
numLikes/numComments, andtopReactionTypesacross a set of profiles to see whose content is actually landing.
📈 How do you monitor engaged leads and decision-maker activity over time?
Monitoring here means re-running the Actor against the same set of profile URLs on a schedule and diffing what changed between runs, rather than treating a single run as a one-off snapshot. Each row carries a scrapedAt timestamp and posts are keyed by a stable urn, so you can match the same post across two runs and see whether numLikes, numComments, or the set of engagedLead child rows attached to it grew. The fields worth diffing are: numLikes, numComments on the parent post, and the list of authorProfileId values across its engagedLead child rows (new profile IDs appearing since the last run are new engagement). A typical workflow: schedule a daily run across your target account list → for each urn seen before, compare its current numComments and child-row count to the prior run → alert when a new decision-maker-level engagedLead (isDecisionMaker: true) shows up on a post you care about. Set this up with an Apify schedule on the Actor, and attach a dataset webhook so each run's results are delivered as soon as the run finishes.
🔌 Integrate LinkedIn Profile Posts Scraper With Lead Enrichment and automate your workflow
LinkedIn Profile Posts Scraper With Lead Enrichment works with any language or tool that can send an HTTP request to the Apify API.
🐍 REST API with Python
import requestsrun_input = {"urls": ["https://www.linkedin.com/in/satyanadella"],"maxPosts": 10,"minSeniorityLevel": "director",}resp = requests.post("https://api.apify.com/v2/acts/YOUR_USERNAME~linkedin-profile-posts-scraper-with-lead-enrichment/run-sync-get-dataset-items",params={"token": "YOUR_APIFY_TOKEN"},json=run_input,)rows = resp.json()for row in rows:if row.get("type") == "post":print(row["authorFullName"], row["seniorityLevel"], row["numComments"])
🕒 Scheduled monitoring and delivery
Set up a recurring Apify schedule against a saved input to re-run the Actor automatically (e.g. daily). Attach a webhook to the run-succeeded event to push each run's dataset items to your own endpoint, or poll the dataset via the Apify API after each scheduled run instead of a live push.
⚖️ Is it legal to scrape LinkedIn profile posts?
Scraping publicly accessible LinkedIn pages is generally lawful in the United States — in hiQ Labs, Inc. v. LinkedIn Corp., 9th Cir., 2019, the court held that scraping data a website makes available to anyone without a login does not violate the Computer Fraud and Abuse Act. This Actor returns only what an anonymous visitor to a public profile or post page can already see; it does not log in, does not bypass a paywall, and does not access private content, and it emits no email or phone field because LinkedIn publishes neither to a logged-out visitor. That said, the posts, comments, and reactor names this Actor returns are personal data about identifiable individuals, so GDPR (if you or the data subjects are in the EU/UK) and CCPA (for California residents) can still apply to how you store, use, and retain it — publicly visible does not mean unregulated. LinkedIn's own Terms of Service also separately restrict automated access for logged-in users, which is a contract question independent of scraping legality. Scraping for one-off research and scraping to build a persistent, resold contact database carry different risk profiles. Consult your legal team for commercial use cases involving bulk personal data storage.
❓ Frequently asked questions
Does LinkedIn Profile Posts Scraper With Lead Enrichment need a LinkedIn login or cookies?
No. It scrapes public profile and post pages anonymously — no li_at cookie, password, or authenticated session is used or required. That is also why it returns no email address, phone number or job-title field: LinkedIn does not publish those to a logged-out visitor, and inventing them would be worse than omitting them.
Can I filter posts by the author's seniority or role?
Yes, with minSeniorityLevel. Set it to manager, director, vp, or executive and only posts whose author's headline classifies at or above that level are kept; any (the default) disables the filter. The classification is a local keyword match against authorHeadline — it is a signal, not a verified title.
How does the Actor handle LinkedIn's anti-bot measures?
LinkedIn's real gate is request rate per source address, not which proxy group you use — and its throttle response is an HTTP 429 carrying about 24 KB of HTML, which a byte-count check happily mistakes for a real page. So the Actor keeps a pool of six Apify Proxy sessions (six distinct exit addresses) per tier, round-robins requests across them, and parks any address that answers 401/403/429/999 for 60–110 seconds instead of retrying it. Only an explicit HTTP 200 is ever parsed. Profile pages start on the datacenter tier and fall through to residential; post permalinks start direct, because they are served to anyone.
Does it extract engaged leads?
Yes — set includeEngagedLeads to true (the default). Every real, named person who commented on a scraped post arrives as its own engagedLead row, linked to the post via parentId, with authorFullName, authorProfileUrl, the comment text and the comment's own reaction count. With enrichLeadProfiles on, the Actor also fetches that lead's own profile page for their headline, employer and location. Those enrichment fields come from the lead's page and only the lead's page — never from the post body, the post author's profile, or another commenter.
How many posts, comments, and reactions does it return per profile?
Up to maxPosts posts per profile (default 10, maximum 200). A profile page publicly lists only its 6–9 most recent posts, so anything beyond that comes from useGoogleDiscovery and depends on Google's index for that person. Per post, LinkedIn renders roughly ten comments to a logged-out visitor; commentsSampled records how many were actually captured while numComments carries the post's real total, so the two are never conflated.
How do I monitor decision-maker engagement over time?
Schedule repeated runs against the same profile URLs and diff numLikes/numComments per urn, plus the authorProfileId values on that post's engagedLead child rows, against the previous run's results. See "How do you monitor engaged leads and decision-maker activity over time?" above for the full workflow.
Does LinkedIn Profile Posts Scraper With Lead Enrichment work with Claude, ChatGPT, and AI agent frameworks?
It has no dedicated MCP server, but it is callable as a plain HTTP endpoint through the Apify API from any agent framework — an agent can trigger a run, poll or receive the dataset, and use the returned JSON (posts and engaged leads) as grounded context before generating an answer.
Can I use it without managing proxies or LinkedIn credentials?
Yes. You never supply a LinkedIn login, cookie, or password — the Actor scrapes anonymously. You also don't need to bring your own proxies: it provisions its own pool of Apify Proxy sessions and rotates across them. You only need an Apify account to run it.
💬 Your feedback
Found a bug, a missing field, or a profile layout the Actor mis-parses? Let us know through the Issues tab on this Actor's page in Apify Console, or contact Scrapier through the Store listing. Reports like this are how the extraction rules stay aligned with LinkedIn's current page structure.