LinkedIn Profile Posts Scraper By Media & Hashtag
Pricing
from $2.99 / 1,000 results
LinkedIn Profile Posts Scraper By Media & Hashtag
π LinkedIn Profile Post Scraper extracts public profile postsβtext, media, hashtags, dates, reactions & comments. π Perfect for B2B marketing, sales, recruiting, social listening & competitor research. βοΈ Clean JSON/CSV for fast, reproducible workflows.
Pricing
from $2.99 / 1,000 results
Rating
0.0
(0)
Developer
SimpleAPI
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
LinkedIn Post Scraper β Profile Posts, Hashtags and Format Type
This LinkedIn post scraper pulls every post from a LinkedIn profile URL and returns it as structured JSON: post text, URL, type (text, image, document, article, or video), hashtags[], numLikes, numComments, author name and headline, and up to the first page of comments and reactions. No LinkedIn login or cookies are used. It runs on an anonymous, publicly-accessible connection and automatically escalates through more resilient connection modes if a request is refused. Marketing teams, social listening tools, and researchers use it to track what a profile posts, how often, in what format, and under which hashtags β without opening a single browser tab.
What is LinkedIn Profile Posts Scraper By Media & Hashtag?
It is an Apify Actor that takes one or more LinkedIn personal profile URLs (linkedin.com/in/...) and returns every post it can reach from that profile as one JSON record per post, plus optional child records for each comment and reaction. No LinkedIn account, login, or session cookie is required β the actor fetches the profile's public pages the way any anonymous visitor's browser would, and results stream into the dataset live as each post is found.
Key features:
- π Profile-URL discovery β give it
/in/URLs; it crawls the post graph reachable from that profile (not just the first page) to collect more than the initial visible batch. - π·οΈ Format classification for every post β each post is tagged
text,image,document,article, orvideo. - #οΈβ£ Free hashtag extraction β every
#hashtagin the post body is parsed into ahashtags[]array with no extra request. - π― Format and media filters β
postTypesandmediaOnlynarrow results before they count against your post limit. - π¬ Comments and reactions as child rows β nested on the post row and also promoted into their own labeled rows for easy filtering/joining.
- πΌοΈ Configurable image cap β
maxImagesPerPostcontrols how many images per carousel post are returned.
What data can I extract with LinkedIn Profile Posts Scraper By Media & Hashtag?
Every post record carries identity, content, format, and engagement fields in one flat JSON object, plus nested comment and reaction detail:
| Field | Example value | Use case |
|---|---|---|
urn | "urn:li:activity:7123456789012345678" | Unique post ID for dedup and joins |
type | "image" | Filter or segment the content mix |
text | "Excited to share our Q3 results! #growth #sales" | Full post copy for NLP / sentiment |
url | "https://www.linkedin.com/posts/janedoe_activity-7123456789012345678" | Direct link back to the post |
hashtags | ["growth", "sales"] | Topic and campaign tagging |
hasImage | true | Quick media-presence flag |
image | "https://media.licdn.com/dms/image/abc123" | First image in the post |
images | ["https://media.licdn.com/...", "..."] | Full carousel, capped by maxImagesPerPost |
postedAtISO | "2026-07-30T14:02:11.000000Z" | Sort/filter by publish date |
postedAtTimestamp | 1785000131000 | Epoch ms for time-series work |
timeSincePosted | "5d" | Human-readable post age |
authorFullName | "Jane Doe" | Who posted |
authorHeadline | "Chief Marketing Officer at Acme Corp" | Role / seniority context |
authorType | "Person" | Author kind (always Person for the accepted input, see Cautions) |
authorProfileUrl | "https://www.linkedin.com/in/janedoe" | Link back to the scraped profile |
authorProfileId | "janedoe" | Stable handle for joins |
author | {"firstName": "Jane", "lastName": "Doe", "occupation": "...", "id": "...", "publicId": "janedoe", "trackingId": "...", "profileId": "...", "picture": "", "backgroundImage": ""} | Nested author identity block |
authorName / authorTitle | "Jane Doe" / "Chief Marketing Officer at Acme Corp" | Flat duplicates of author name/headline |
attributes | [{"type": "PROFILE_MENTION", "profile": {...}}] | @mentions inside the post text/HTML |
scrapedAt | "2026-08-04T09:15:00.000000Z" | Freshness / re-scrape scheduling |
Engagement data β comments and reactions
Every post row carries numLikes and numComments, plus a nested comments[] and reactions[] array taken from the post's own page. Each is capped to the first min(10, numComments) comments and min(20, numLikes) reactions found on that page β commentsTruncated / reactionsTruncated tell you when more exist beyond that slice, and commentsComplete tells you when the full comment count was captured. Every comment and reaction is also promoted into its own dataset row (type: "comment" / type: "reaction", isChild: true, parentId set to the parent post's urn, plus parentUrl, authorFullName, authorProfileId, and either link/commentedAtTimestamp for comments or reactionType for reactions) so you can filter or join engagement data without unpacking nested arrays. numShares, isRepost, and the platform-visibility flags canReact, canPostComments, canShare, commentingDisabled, allowedCommentersScope, rootShare, and shareAudience are only observable with an authenticated LinkedIn session β on this anonymous surface they are always returned as null rather than a guessed value.
Format and hashtag data β targeting fields
type, hashtags, and hasImage are the fields you filter on. type is set per post ( article from LinkedIn's own structured-data marker, which is reliable; document and video from HTML markers checked only on that post's own single-post page, which is best-effort; text/image from whether the post carries an image, which is fully reliable). hashtags is a de-duplicated, order-preserving list pulled straight from the post text. These three fields are exactly what postTypes and mediaOnly filter on before a post counts toward maxPosts.
Why not build this yourself?
LinkedIn's own developer platform does not offer a public API for pulling posts from an arbitrary public profile you don't own. Access is gated behind LinkedIn's Partner Program, and even approved integrations are largely limited to identity sign-in and a member's own content β not bulk retrieval of another profile's post history (observed on LinkedIn's developer documentation, checked 2026-08-04). Building this yourself without an API means handling LinkedIn's anti-bot detection (999/403/429 responses), rotating proxies, session warm-up, retry/backoff logic, and HTML structure that changes over time β all before you get to parsing post format, hashtags, comments, and reactions out of raw markup.
This actor already does that work: it starts on a direct connection, automatically escalates to a datacenter and then a residential proxy strategy when a request is refused, retries with backoff on 429s, and normalizes everything into one consistent JSON schema per post. Use LinkedIn's own developer program if you're building an app that acts on a user's own authenticated account; use this actor when you need structured post data from public profiles at all.
How to use data extracted from LinkedIn?
Marketing and social media teams
Pull a competitor's or an executive's last maxPosts posts, filter to postTypes: ["image", "video"] to see what visual content performs, and cross-reference hashtags[] against your own campaign tags to spot topics you're missing. numLikes and numComments on each row let you rank posts by engagement without opening LinkedIn.
Agencies auditing client or competitor accounts
Run the same input list of profile URLs on a schedule and diff type distribution and posting cadence (postedAtISO) run over run to show clients how their content mix β or a competitor's β is shifting month to month, without manually opening each profile.
Market research and content intelligence
Aggregate hashtags[] and type across a set of executive or company profiles to map which topics and formats a sector is posting about, and use authorHeadline to segment findings by seniority or function.
AI agents and automated pipelines
Feed a set of profile URLs into an agent that filters on mediaOnly or postTypes, then summarizes text and comments[] for sentiment or outreach personalization β the actor is a plain HTTP/SDK call, so it drops into any agent framework without a browser dependency.
πΌ Input sample
| Parameter | Required | Type | Description | Example value |
|---|---|---|---|---|
urls | Yes | array | LinkedIn profile URLs to scrape, one per line. | ["https://www.linkedin.com/in/ajjames"] |
maxPosts | No | integer | Max posts per URL that pass the filters below (min 1, max 500, default 10). | 25 |
postTypes | No | array | Only return posts of these formats: text, image, document, article, video. Empty returns all formats (default []). | ["image", "article"] |
maxImagesPerPost | No | integer | Max images returned per post (min 0, max 20, default 5). | 3 |
mediaOnly | No | boolean | Only return posts with at least one image (default false). | false |
rateLimitDelay | No | integer | Base delay in seconds between page fetches, jittered (min 0, max 60, default 1). | 1 |
fetchRetries | No | integer | Retries per request before giving up on it (min 0, max 10, default 3). | 3 |
proxyConfiguration | No | object | Apify Proxy settings. No proxy is used by default; the actor falls back automatically if requests are refused. | {"useApifyProxy": false} |
Example input
{"urls": ["https://www.linkedin.com/in/ajjames","https://www.linkedin.com/in/satyanadella"],"maxPosts": 25,"postTypes": ["image", "article"],"maxImagesPerPost": 3,"mediaOnly": false,"rateLimitDelay": 1,"fetchRetries": 3,"proxyConfiguration": { "useApifyProxy": false }}
Common pitfall: only /in/ personal profile URLs are accepted. Company (/company/), feed, post, school, or group URLs are silently skipped with a warning in the run log rather than an error β double-check every URL in your urls list points at a personal profile if a run returns fewer rows than expected.
π½ Output sample
Results are typed, normalized JSON pushed to the dataset live as they're found. Export the dataset as JSON, CSV, Excel, or a single overview HTML/XML table from the Apify Console or API β no format conversion needed. One post record looks like this:
{"urn": "urn:li:activity:7123456789012345678","text": "Excited to share our Q3 results! #growth #sales","url": "https://www.linkedin.com/posts/janedoe_activity-7123456789012345678","postedAtTimestamp": 1785000131000,"postedAtISO": "2026-07-30T14:02:11.000000Z","timeSincePosted": "5d","isRepost": null,"authorType": "Person","authorProfileUrl": "https://www.linkedin.com/in/janedoe","authorProfileId": "janedoe","authorHeadline": "Chief Marketing Officer at Acme Corp","authorFullName": "Jane Doe","image": "https://media.licdn.com/dms/image/abc123","type": "image","images": ["https://media.licdn.com/dms/image/abc123"],"hashtags": ["growth", "sales"],"hasImage": true,"author": {"firstName": "Jane","lastName": "Doe","occupation": "Chief Marketing Officer at Acme Corp","id": "janedoe","publicId": "janedoe","trackingId": "aBcDeFgHiJkLmNoPqRs","profileId": "janedoe","picture": "","backgroundImage": ""},"authorName": "Jane Doe","authorTitle": "Chief Marketing Officer at Acme Corp","attributes": [],"comments": [],"reactions": [],"numShares": null,"numLikes": 128,"numComments": 14,"commentsTruncated": false,"commentsComplete": true,"reactionsTruncated": false,"canReact": null,"canPostComments": null,"canShare": null,"commentingDisabled": null,"allowedCommentersScope": null,"rootShare": null,"shareAudience": null,"scrapedAt": "2026-08-04T09:15:00.000000Z"}
A promoted comment child row looks like this:
{"type": "comment","isChild": true,"parentId": "urn:li:activity:7123456789012345678","parentUrl": "https://www.linkedin.com/posts/janedoe_activity-7123456789012345678","text": "Congrats on the results!","authorFullName": "John Smith","authorProfileId": "johnsmith","link": "https://www.linkedin.com/feed/update/comment/12345","commentedAtTimestamp": 1785000200000,"scrapedAt": "2026-08-04T09:15:00.000000Z"}
Note: the isChild and parentId keys only exist on comment and reaction child rows. Parent post rows do not carry an isChild key at all β filter on type ("comment" / "reaction" vs. everything else) if you need to split parents from children programmatically.
How do you filter and target specific posts?
This actor's targeting controls sit on top of maxPosts, which is applied after the filters below β only posts that pass postTypes/mediaOnly count toward your limit, so a tight filter with a low maxPosts can still require crawling far more of a profile's history than the number returned.
- Format filtering (
postTypes) β pass["image", "video"]to keep only visual content, or["article", "document"]for long-form posts. Leave it empty to get every format. Remember thatdocumentandvideodetection is best-effort HTML-marker matching, whiletext,image, andarticleare reliably detected (see the format section above). - Media-presence filtering (
mediaOnly) β a blunter version of format filtering:truereturns only posts with at least one image, regardless of format tag, which is useful when you just need a media library and don't care about the exact format split. - Image volume (
maxImagesPerPost) β controls carousel depth per post, from 0 (skip image extraction entirely) up to 20; keep it low if you only need a thumbnail per post. - Post volume (
maxPosts) β the per-URL cap on how many filtered-in posts to return, from 1 to 500; the crawl stops as soon as this many posts have passed your filters, so a highly restrictivepostTypesfilter combined with a highmaxPostscan mean a longer run against a profile with few matching posts.
Three real examples, each solving a different targeting problem:
{ "urls": ["https://www.linkedin.com/in/janedoe"], "postTypes": ["image"], "mediaOnly": true, "maxImagesPerPost": 3, "maxPosts": 20 }
{ "urls": ["https://www.linkedin.com/in/janedoe"], "postTypes": ["article", "document"], "maxPosts": 15 }
{ "urls": ["https://www.linkedin.com/in/janedoe"], "postTypes": [], "maxImagesPerPost": 10, "maxPosts": 200 }
βΆοΈ Want to try other LinkedIn scrapers?
| Scraper | What it extracts |
|---|---|
| LinkedIn Search Jobs Scraper With Advanced Search Filters | LinkedIn job listings, narrowed by workplace type, experience level, employment type, date posted, and salary band |
| Facebook Group Posts And Details & Contact Leads Scraper | Facebook group posts, group profile details, and member contact leads |
| Threads Search Post Scraper | Threads posts by URL, post ID, or search phrase, with engagement and mentions |
| Twitter X Tweets Scraper Scraper By Keyword & Hashtag | X (Twitter) posts by keyword or hashtag with typed engagement filters |
| TikTok Data Scraper β Video, Hashtag & Sound Performance | TikTok videos, hashtags, sounds, and profile/comment data |
How to extract LinkedIn data programmatically
This actor runs like a standard Apify Actor: one API call starts the run, and results land in a dataset you read back over the Apify REST API or an official client library β no separate signup or API key beyond your Apify account token.
Python example
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("your-username/linkedin-profile-posts-scraper-by-media-and-hashtag").call(run_input={"urls": ["https://www.linkedin.com/in/janedoe"],"maxPosts": 25,"postTypes": ["image", "article"],})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["type"], item.get("numLikes"), item.get("hashtags"))
Export to spreadsheets or CRM
From the Apify Console's Output tab, export the dataset directly to CSV or Excel and map authorFullName β Contact Name, authorProfileUrl β Contact URL, text β Notes, and numLikes/numComments β engagement columns in your CRM import template.
Is it legal to scrape LinkedIn?
Scraping publicly visible LinkedIn posts and profile information is generally lawful β these pages are published without a login wall, and the 9th Circuit's ruling in hiQ Labs v. LinkedIn held that scraping data that's publicly accessible does not violate the U.S. Computer Fraud and Abuse Act. That said, the same litigation ultimately settled in December 2022 with hiQ enjoined from scraping LinkedIn under state-law claims tied to LinkedIn's terms of use (checked 2026-08-04) β so a CFAA defense does not clear you of a terms-of-service dispute. Because this actor's output includes personal data β names, headlines, and comment/reaction authorship of real individuals β GDPR, CCPA, and similar regimes govern how you may store, process, and reuse it, separately from any platform ToS question. Consult legal counsel for commercial applications involving bulk storage of personal data.
β FAQ
What happens if a post is deleted or edited after I scrape it?
The dataset holds a snapshot of the post exactly as its public page looked at scrapedAt. The actor does not track a post afterward or flag deletions/edits β if you need to know a post's current state, re-run against the same profile URL and compare urn values.
Can I get comments and reactions along with the posts?
Yes. Each post row carries nested comments[] and reactions[], and both are also promoted into their own dataset rows. Comments are capped to the first min(10, numComments) found on the post's page and reactions to the first min(20, numLikes) β commentsTruncated/reactionsTruncated flag when more exist beyond that.
How accurate is the engagement data?
numLikes and numComments reflect the counts on the page at the moment it was fetched. If a post keeps gaining engagement after your run finishes, those numbers will lag until you scrape it again.
How many posts can I get per run?
Up to maxPosts per URL (1β500, default 10), counting only posts that pass your postTypes/mediaOnly filters. There is no separate hard platform cap enforced in the code beyond that input maximum.
How do I get only a specific content format?
Set postTypes to any combination of text, image, document, article, video. document and video are detected from best-effort HTML markers checked only on a post's own page, so treat them as a strong signal rather than a guarantee β text, image, and article detection is reliable.
Does this scraper work with company or group pages?
No β only personal profile URLs (/in/...) are processed. Company, feed, post, school, and group URLs are skipped with a warning logged for that URL, and no rows are produced for it.
Does LinkedIn Profile Posts Scraper By Media & Hashtag work with Claude, ChatGPT, and AI agent frameworks?
Yes, as a plain HTTP/SDK call. It's not registered as an MCP server, but any agent framework that can call the Apify API or apify-client can start a run and read back the dataset like any other tool call.
Can I use this without a LinkedIn account or API key?
Yes. It requires no LinkedIn login, cookies, or API key β only a LinkedIn profile URL. You do need an Apify account token to run the actor itself.
Conclusion
LinkedIn Profile Posts Scraper By Media & Hashtag turns a list of LinkedIn profile URLs into structured, format-classified post data β complete with hashtags, engagement counts, and comment/reaction detail β without a login, cookies, or manual scrolling. It's built for marketers, agencies, researchers, and AI pipelines that need a profile's actual posting history as clean JSON rather than screen-scraped HTML. Open the actor in the Apify Console, paste in your profile URLs, and start a run to see it in action.