LinkedIn Profile Posts Scraper With Engagement Analytics
Pricing
from $3.99 / 1,000 results
LinkedIn Profile Posts Scraper With Engagement Analytics
LinkedIn Profile Post Scraper extracts posts from any LinkedIn profile. Collect post text, dates, reactions, comments, and engagement metrics. Ideal for content research, competitor monitoring, influencer analysis, and tracking professional activity across LinkedIn profiles.
Pricing
from $3.99 / 1,000 results
Rating
0.0
(0)
Developer
Scrapio
Maintained by CommunityActor stats
0
Bookmarked
8
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share
LinkedIn Post Scraper β Extract Posts, Comments and Reactions
LinkedIn Profile Posts Scraper With Engagement Analytics extracts posts, comments, and reactions from any public LinkedIn profile as structured JSON β no login, cookie, or li_at session required. Every post ships with derived engagement metrics (engagementRate, likesPerDay, postingCadenceDays, engagementRank) computed locally from the same counts the actor already scrapes, plus an exact post timestamp decoded straight from LinkedIn's own Snowflake-style activity ID. Unlike scraping frameworks that return raw HTML, this actor returns typed JSON β ready for your model, your database, or your pipeline without any parsing. This guide covers every input and output field, and how teams deploy it for enrichment, monitoring, and dataset building.
π§ What Does LinkedIn Profile Posts Scraper With Engagement Analytics Do?
LinkedIn Profile Posts Scraper With Engagement Analytics visits one or more public LinkedIn profile pages (URLs matching /in/...) and crawls the posts published there, following in-page post links to collect more posts than the profile's initial feed view exposes. No LinkedIn account, login, or li_at session cookie is required β the actor reads the same publicly rendered page an anonymous, logged-out visitor sees. Every post row is enriched with an exact, Snowflake-decoded timestamp and a set of derived engagement-analytics fields, while any comments and reactions rendered on the page are promoted to their own labeled child rows in the same output table.
Key capabilities:
- π Extracts posts from any public LinkedIn profile URL (
/in/...) β no login required - π Decodes each post's exact creation timestamp from its activity ID (
exactPostedAtISO), independent of the date text rendered on the page - π Computes
engagementRate,postAgeDays,likesPerDay,postingCadenceDays, andengagementRankfor every post - π¬ Promotes each comment and reaction visible on the page into its own labeled child dataset row
- β‘ Streams results to the Output table in real time as each post is scraped, not buffered until the run ends
- π Escalates automatically between direct, datacenter, and residential proxy strategies if LinkedIn temporarily restricts access
- π« Returns fields the anonymous page can't verify (
numShares,isRepost, permission flags) asnullrather than a guessed value
β‘ Features & Capabilities
Capabilities fall into three areas: what gets extracted, how the derived analytics are computed, and how the actor keeps running when LinkedIn pushes back.
Core features
- Post capture β
urn,text,url,postedAtISO,timeSincePosted,authorFullName,authorHeadline,authorType,numLikes,numComments - Exact timestamp verification β
exactPostedAtISO,exactPostedAtTimestamp,dateCrossCheckMatch,dateCrossCheckDeltaMs, decoded directly from the post's Snowflake-style activity ID (timestamp_ms = int(activity_id) >> 22), zero extra requests - Engagement analytics β
engagementRate,postAgeDays,likesPerDay,postingCadenceDays,engagementRank, computed locally from counts already scraped; no AI model and no third-party API involved - Comment and reaction child rows β each entry in a post's
comments[]/reactions[]is also emitted as its own dataset row (type: "comment"/"reaction",isChild: true,parentIdpointing back to the post'surn) - Real-time output β every post, and every comment/reaction child row derived from it, is pushed to the dataset the moment it's scraped
- Automatic connection escalation β direct connection β Apify Proxy datacenter β Apify Proxy residential, triggered by 401/403/429/999 responses or CAPTCHA/forbidden page text
When another tool might suit you better
This actor is built for the anonymous, public view of a profile's post history β it never logs in, so fields LinkedIn only exposes to an authenticated viewer (exact share counts, comment/reaction permission flags, genuine repost detection) always return null here. If your workflow needs those fields, or needs a profile's full historical post archive beyond what the public page renders and links to, a session-based scraper that authenticates with a LinkedIn account is a better fit than this one. This actor trades that depth for zero login risk and zero account-ban exposure.
LinkedIn Profile Posts Scraper With Engagement Analytics within the Scrapio data stack
LinkedIn Profile Posts Scraper With Engagement Analytics covers profile posts, comments, and reactions. For LinkedIn job listings and hiring-market analytics from the same account, use LinkedIn Search Jobs Scraper With Market Analytics.
πΌ Why do developers and data teams scrape LinkedIn?
π’ Sales, marketing and social-selling teams
Feed a list of prospect, partner, or account-executive profile URLs into urls and get back each person's recent posting activity β text, authorHeadline, numLikes, numComments, and the derived engagementRate β without opening LinkedIn one profile at a time. A sales-enablement team can use this to flag which target accounts have an active, engaged decision-maker posting regularly (a good outbound signal) versus one who hasn't posted in months. The output lands directly in the Apify dataset, from where it's exported to a CRM, a spreadsheet, or a Slack alert as part of an account-research workflow.
π AI training data and RAG indexing
The text field β each post's full body copy β is the highest-information field for both RAG indexing and training data here: it's the actual professional commentary a person or company chose to publish, paired with authorHeadline and postedAtISO for retrieval context. For RAG enrichment, indexing text alongside authorFullName and authorProfileUrl lets an agent answer "what has this person recently said about X" from a vector store instead of a live scrape. For training data, every field returns as a typed primitive (string, number, boolean, or null) with a stable key set across runs, so a dataset of thousands of posts needs no per-record normalization before it's usable.
π± Competitive and market intelligence
Run the actor on a recurring schedule against a fixed list of competitor executives, founders, or brand accounts, and track engagementRate and postingCadenceDays over time. A sharp jump in engagementRate on a specific post, or a shortening postingCadenceDays, signals a change in a competitor's content strategy worth a closer look β a product launch, a hiring push, or a new content cadence β before it shows up anywhere else.
π¬ Research and academic use
Social-media and organizational-behavior researchers use profile-level post data like this to study public posting cadence, engagement distribution, and content patterns among professional or public figures. This actor returns only publicly accessible data β no private posts, no authenticated-only fields β which keeps the dataset within the boundaries of public-data research.
π₯ Product and SaaS development
Teams building creator-analytics dashboards, LinkedIn "scorecards," or lead-enrichment add-ons use this actor as the backend data source: engagementRank and postingCadenceDays slot directly into a scoring model without you having to compute engagement math from raw counts yourself.
π Input Parameters
All inputs are read directly from .actor/actor.json. urls is the only required parameter.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
urls | Yes | array | LinkedIn profile URLs to scrape. Add one or more, one per line. Only personal profile URLs (/in/...) are processed β any other URL type is skipped with a warning. | ["https://www.linkedin.com/in/satyanadella"] |
maxPosts | No | integer | Maximum number of posts to collect per URL. Minimum 1, maximum 500. Keep lower for faster runs (e.g. 10β50). Default: 20. | 20 |
includeAnalytics | No | boolean | When true, each post gets engagementRate, postAgeDays, likesPerDay, postingCadenceDays, and engagementRank fields computed from real scraped counts. When false, these fields are null. Default: true. | true |
verifyTimestampWithSnowflake | No | boolean | When true, decodes the exact post creation timestamp from the numeric activity ID embedded in the post URN (zero extra requests) and cross-checks it against the date parsed from the page. When false, only the page-parsed date is used. Default: true. | true |
rateLimitDelay | No | integer | Base delay in seconds between requests while crawling a profile's posts. Minimum 0, maximum 30. Higher values are gentler but slower. Default: 1. | 1 |
fetchRetries | No | integer | Number of retries per HTTP request before giving up on a page. Minimum 0, maximum 10. Default: 3. | 3 |
proxyConfiguration | No | object | Apify Proxy configuration. By default uses no proxy β the actor automatically escalates to a more resilient connection strategy if LinkedIn temporarily restricts requests. Optional: enable Apify Proxy here to start with a specific setup. | {"useApifyProxy": false} |
Example input
{"urls": ["https://www.linkedin.com/in/satyanadella","https://www.linkedin.com/in/ajjames"],"maxPosts": 20,"includeAnalytics": true,"verifyTimestampWithSnowflake": true,"rateLimitDelay": 1,"fetchRetries": 3}
Supported URL types and input formats
Only personal profile URLs are accepted. The actor classifies every input URL and, if it doesn't resolve to a /in/... profile page, skips it and logs a warning rather than failing the run β company, feed, individual post, school, and group URLs are all recognized internally but rejected at this input filter.
- β
https://www.linkedin.com/in/satyanadellaβ personal profile, processed - β
https://linkedin.com/in/ajjamesβ bare-domain form, normalized tohttps://www.linkedin.com/in/ajjamesbefore fetching - β
https://www.linkedin.com/company/microsoftβ company page, skipped with a warning (not a profile URL)
π¦ Output Format
Output is typed, normalized JSON with a consistent field set across runs, delivered to the Actor's default dataset. Export it as JSON, CSV, Excel, or query it directly through the Apify API β whichever format your pipeline needs. Every pushed row β each post, each promoted comment, and each promoted reaction β is billed under the same row_result pay-per-event charge, so a post with several comments and reactions attached produces several charged rows, not one.
Output for posts
{"urn": "urn:li:activity:7123456789012345678","type": "text","isChild": false,"parentId": null,"url": "https://www.linkedin.com/feed/update/urn:li:activity:7123456789012345678","text": "Excited to share our latest platform update...","postedAtTimestamp": 1731000000000,"postedAtISO": "2024-11-07T12:00:00.000000Z","exactPostedAtTimestamp": 1731000012345,"exactPostedAtISO": "2024-11-07T12:00:12.345000Z","dateCrossCheckMatch": true,"dateCrossCheckDeltaMs": 12345,"timeSincePosted": "3mo","authorType": "Person","authorProfileUrl": "https://www.linkedin.com/in/satyanadella","authorProfileId": "satyanadella","authorHeadline": "Chairman and CEO at Microsoft","authorFullName": "Satya Nadella","authorName": "Satya Nadella","authorTitle": "Chairman and CEO at Microsoft","author": {"firstName": "Satya","lastName": "Nadella","occupation": "Chairman and CEO at Microsoft","id": "satyanadella","publicId": "satyanadella","trackingId": "3jH8sK2pQ1zAbCdEfGhIjw==","profileId": "satyanadella","picture": "https://media.licdn.com/dms/image/profile.jpg","backgroundImage": ""},"image": "https://media.licdn.com/dms/image/xyz.jpg","images": ["https://media.licdn.com/dms/image/xyz.jpg"],"attributes": [],"numLikes": 4820,"numComments": 312,"numShares": null,"isRepost": null,"comments": [{"time": 1731003600000,"link": "https://www.linkedin.com/feed/update/comment/1234567","text": "Great milestone, congrats to the team!","entities": [],"pinned": false,"originalLanguage": "English","author": {"firstName": "Jane","lastName": "Doe","occupation": "","id": "commenter-9f3a1b2c4d5e","publicId": "jane-doe","trackingId": "aB1cD2eF3gH4iJ5k","profileId": "commenter-9f3a1b2c4d5e","picture": "","backgroundImage": "","distance": "OUT_OF_NETWORK"}}],"reactions": [{"type": "LIKE","profile": {"firstName": "John","lastName": "Smith","occupation": "","id": "reactor-7c2d9e1f0a3b","publicId": "john-smith","trackingId": "kL6mN7oP8qR9sT0u","profileId": "ACoAA7c2d9e1f0a3b","picture": "","backgroundImage": ""}}],"commentsTruncated": false,"commentsComplete": true,"reactionsTruncated": true,"canReact": null,"canPostComments": null,"canShare": null,"commentingDisabled": null,"allowedCommentersScope": null,"rootShare": null,"shareAudience": null,"engagementRate": 57.022,"postAgeDays": 90.0,"likesPerDay": 53.556,"postingCadenceDays": 4.25,"engagementRank": 98.4,"scrapedAt": "2026-08-04T10:15:32.000000Z"}
Fields the public, logged-out LinkedIn page genuinely cannot confirm (
numShares,isRepost,canReact,canPostComments,canShare,commentingDisabled,allowedCommentersScope,rootShare,shareAudience) are returned asnullrather than a guessed value.
Output for comments
Each comment already rendered on the page is also pushed as its own child row, separate from the nested comments[] array on the parent post:
{"type": "comment","isChild": true,"parentId": "urn:li:activity:7123456789012345678","parentUrl": "https://www.linkedin.com/feed/update/urn:li:activity:7123456789012345678","commentText": "Great milestone, congrats to the team!","commentAuthorName": "Jane Doe","commentAuthorProfileId": "commenter-9f3a1b2c4d5e","commentAuthorPublicId": "jane-doe","commentLink": "https://www.linkedin.com/feed/update/comment/1234567","commentTimestamp": 1731003600000,"scrapedAt": "2026-08-04T10:15:32.000000Z"}
Output for reactions
{"type": "reaction","isChild": true,"parentId": "urn:li:activity:7123456789012345678","parentUrl": "https://www.linkedin.com/feed/update/urn:li:activity:7123456789012345678","reactionType": "LIKE","reactorName": "John Smith","reactorProfileId": "reactor-7c2d9e1f0a3b","reactorPublicId": "john-smith","reactorProfileUrl": "https://www.linkedin.com/in/john-smith","scrapedAt": "2026-08-04T10:15:32.000000Z"}
Schema stability and export options
Field names stay stable across runs β the actor doesn't rename or drop keys when LinkedIn updates its front end; if a value becomes unavailable, it's returned as null rather than the key being removed. Export the dataset as JSON, CSV, or Excel from the Apify Console, or pull it programmatically through the Apify API or apify-client SDKs. comments[]/reactions[] coverage on the parent post row (and the child rows derived from them) is best-effort: LinkedIn's anonymous page shell doesn't always render full engagement detail, which is why commentsTruncated, commentsComplete, and reactionsTruncated are included on every post β filter on those flags if your use case needs to know when the visible set is incomplete.
π‘ LinkedIn Profile Posts Scraper With Engagement Analytics Strategy Guide
π― Strategy 1: Real-time enrichment pipeline
Trigger this actor whenever a new lead, creator, or account enters your CRM or spreadsheet. Feed their profile URL into urls, run with includeAnalytics: true, and append engagementRate, engagementRank, and postingCadenceDays back onto that record the moment the run finishes. A team scoring inbound creators or prospects for a partnership program can use engagementRank β the post's percentile rank by total engagement among posts scraped so far in the run β as a fast proxy for "is this person actually active and engaged," without opening LinkedIn manually for each name on the list.
π― Strategy 2: Scheduled monitoring and alerting
Schedule the actor to run daily or weekly against the same list of profile URLs using Apify's built-in Schedules. On each run, diff the new dataset against the previous run's export on urn (new posts) and on numLikes/numComments for posts seen before (engagement still accruing). Alert your team when engagementRate on a tracked profile's post jumps sharply, or when postingCadenceDays shortens noticeably β both signal a change in posting behavior worth a closer look.
π― Strategy 3: Bulk dataset build
For a research or training dataset, pass a large urls list (one profile per line) in a single run, or fan out multiple runs across profile batches via the Apify API β how many you can run in parallel depends on your Apify plan's concurrency allowance, not a limit set by this actor. Aggregate the resulting dataset exports (CSV, JSON, or Excel, via the Apify Console or API) across runs, using authorProfileId and postedAtISO as your join keys.
Strategy comparison at a glance
| Strategy | Best for | Run pattern | Output format |
|---|---|---|---|
| Real-time enrichment | Scoring individual leads/creators as they appear | Single run per new profile | JSON row appended per profile |
| Scheduled monitoring | Tracking a fixed list of profiles over time | Recurring run via Apify Schedules | Dataset diffed run-over-run |
| Bulk dataset build | Research or training datasets | One large urls list, or batched parallel runs | CSV/JSON/Excel export |
π΄ Related LinkedIn Scrapers & Tools
| Scraper Name | What it extracts |
|---|---|
| LinkedIn Search Jobs Scraper With Market Analytics | LinkedIn job listings with hiring-market analytics (same account) |
| X (Twitter) User Profile and Tweets Scraper With Follower Lists | Tweets and profile data from X/Twitter, for the same cross-platform "profile posts" use case |
| Twitter X Tweets Scraper With Poll Results | Tweets and poll results from X/Twitter |
| Threads Search Post Scraper With Engagement Analytics | Posts and engagement analytics from Meta's Threads |
| Facebook Group Posts And Details Scraper | Posts and group details from Facebook Groups, for adjacent social-monitoring workflows |
| TikTok Data Scraper (Comments, Replies and AI Sentiment) | TikTok video comments and replies with sentiment scoring, for adjacent engagement-analysis workflows |
How to integrate LinkedIn Profile Posts Scraper With Engagement Analytics with your stack
LinkedIn Profile Posts Scraper With Engagement Analytics works with any language or tool that can make an HTTP request β it runs on Apify and is called through the Apify API or the official apify-client SDKs.
Python
from apify_client import ApifyClientimport csvclient = ApifyClient("<YOUR_APIFY_TOKEN>")profile_urls = ["https://www.linkedin.com/in/satyanadella","https://www.linkedin.com/in/ajjames",]run_input = {"urls": profile_urls,"maxPosts": 20,"includeAnalytics": True,"verifyTimestampWithSnowflake": True,}run = client.actor("YOUR_USERNAME/linkedin-profile-posts-scraper-with-engagement-analytics").call(run_input=run_input)rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())posts = [r for r in rows if not r.get("isChild")]with open("linkedin_posts.csv", "w", newline="", encoding="utf-8") as f:fields = ["authorFullName", "postedAtISO", "text", "numLikes", "numComments", "engagementRate", "engagementRank"]writer = csv.DictWriter(f, fieldnames=fields)writer.writeheader()for p in posts:writer.writerow({k: p.get(k) for k in fields})print(f"Wrote {len(posts)} posts to linkedin_posts.csv")
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('YOUR_USERNAME/linkedin-profile-posts-scraper-with-engagement-analytics').call({urls: ['https://www.linkedin.com/in/satyanadella'],maxPosts: 20,includeAnalytics: true,});const { items } = await client.dataset(run.defaultDatasetId).listItems();const posts = items.filter((r) => !r.isChild);posts.forEach((p) => {console.log(`${p.authorFullName} β ${p.numLikes} likes β engagementRate ${p.engagementRate}`);});
Async and scheduled pipelines
This actor has no webhook or scheduling logic of its own β those are Apify platform features available to any Actor. Use Apify Schedules to run it on a recurring cadence, or attach a webhook to the run's SUCCEEDED event to get notified β or trigger a downstream job β as soon as a run's dataset is ready, instead of polling the API for run status.
π― Who Needs LinkedIn Profile Posts Scraper With Engagement Analytics? (Use Cases & Industries)
π’ Sales and social-selling teams
A sales-enablement team pulls urls for a target account list and checks numLikes, numComments, and engagementRate on each executive's recent posts to prioritize outreach toward decision-makers who are visibly active on LinkedIn, rather than cold-emailing everyone equally.
π AI engineers building RAG and enrichment pipelines
Teams building an enrichment API index each post's text and authorHeadline into a vector store, using postedAtISO to keep results chronologically ordered, so an agent can answer "what has this account recently posted about" without a live scrape on every query.
π± Competitive and market-intelligence analysts
Analysts run the actor on a schedule against competitor executives and brand accounts, watching engagementRate and postingCadenceDays for shifts that flag a new content push, product announcement, or hiring campaign before it's covered elsewhere.
π¬ Researchers
Academic and social-media researchers use the actor to build public-data datasets of posting cadence and engagement distribution among professional or public figures, staying within the actor's public-data-only scope.
π₯ Product and SaaS builders
Teams building creator-analytics or lead-scoring products use engagementRank and postingCadenceDays as ready-made model inputs instead of writing their own engagement-math layer on top of raw like/comment counts.
βοΈ Is it legal to scrape LinkedIn?
Scraping publicly accessible LinkedIn profile data is generally lawful in the United States. In hiQ Labs, Inc. v. LinkedIn Corp. (9th Circuit, 2019), the court held that scraping data a website makes publicly available, without bypassing an authentication wall, does not violate the Computer Fraud and Abuse Act. That ruling addressed the CFAA specifically β it does not clear LinkedIn's own Terms of Service, which prohibit automated data collection; violating them is a civil, contractual risk between you and LinkedIn, not a criminal one. Because this actor returns personal data β names, profile URLs, headlines, and the names of commenters and reactors β you also take on data protection obligations: under frameworks like GDPR and CCPA, you are the controller for whatever personal data you store and process, and you need a lawful basis for that use. LinkedIn Profile Posts Scraper With Engagement Analytics returns only publicly accessible data. What you do with that data is your responsibility β consult legal counsel for commercial applications involving personal data.
β Frequently asked questions
Does LinkedIn Profile Posts Scraper With Engagement Analytics work without a LinkedIn account?
Yes. No LinkedIn login, cookie, or li_at session is required β the actor reads the same publicly rendered profile page an anonymous, logged-out visitor sees.
How does it handle LinkedIn's anti-scraping measures?
It starts with a direct connection and a warmed-up browser-like session, then escalates automatically to Apify Proxy's datacenter tier and, if still blocked, its residential tier, whenever a response comes back with status 401, 403, 429, or 999, or the page text contains a CAPTCHA/forbidden marker. Requests that fail are retried with exponential backoff (fetchRetries, default 3), and a base delay (rateLimitDelay, default 1 second) with random jitter is applied between requests while crawling a profile's posts.
Can I run it at scale without getting blocked?
The actor's proxy-escalation and retry logic reduce blocking, but there's no published uptime or success-rate guarantee β LinkedIn's anonymous page shell can still return incomplete results for comments[]/reactions[], and if your Apify account has no quota on the residential proxy group, the actor falls back to the datacenter tier automatically rather than failing the run.
How fresh is the data it returns?
It's a live fetch on every run β each run makes fresh HTTP requests to the profile's current page state. postingCadenceDays and engagementRank, however, are computed cumulatively from the posts seen so far within that run, not from any historical dataset, so their values reflect the current run's scope, not the profile's all-time history.
Which LinkedIn fields work best for AI training and RAG indexing?
For RAG, index text (the post body) alongside authorHeadline and postedAtISO for retrieval context. For training data, numLikes, numComments, engagementRate, postAgeDays, and engagementRank are the most consistently structured numeric fields across records. Every field returns as a typed primitive β string, number, boolean, or null β so none of it needs normalization before it goes into a model's context window.
What happens with data about the people who comment and react on a post?
Comment and reaction authors' names, LinkedIn public IDs, and profile links are personal data, the same as the post author's. This actor returns only what's already publicly visible on the page; lawful basis for storing and using that data β including under GDPR, CCPA, or similar laws β sits with you as the person running the actor.
Does it work with Claude, ChatGPT, and other AI agent tools?
There's no dedicated MCP server for this actor. It's callable as an HTTP endpoint by any agent framework via the Apify API or apify-client β every response is typed JSON, so an agent can consume it directly without parsing HTML.
βΉοΈ Disclaimer
LinkedIn Profile Posts Scraper With Engagement Analytics extracts only publicly available data from LinkedIn. This tool is intended for lawful use cases only. Users are responsible for complying with LinkedIn's terms of service and applicable data protection laws in their jurisdiction.