LinkedIn Profile Posts Scraper By Media & Hashtag avatar

LinkedIn Profile Posts Scraper By Media & Hashtag

Pricing

from $2.99 / 1,000 results

Go to Apify Store
LinkedIn Profile Posts Scraper By Media & Hashtag

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

SimpleAPI

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

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, or video.
  • #️⃣ Free hashtag extraction β€” every #hashtag in the post body is parsed into a hashtags[] array with no extra request.
  • 🎯 Format and media filters β€” postTypes and mediaOnly narrow 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 β€” maxImagesPerPost controls 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:

FieldExample valueUse 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
hasImagetrueQuick 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
postedAtTimestamp1785000131000Epoch 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

ParameterRequiredTypeDescriptionExample value
urlsYesarrayLinkedIn profile URLs to scrape, one per line.["https://www.linkedin.com/in/ajjames"]
maxPostsNointegerMax posts per URL that pass the filters below (min 1, max 500, default 10).25
postTypesNoarrayOnly return posts of these formats: text, image, document, article, video. Empty returns all formats (default []).["image", "article"]
maxImagesPerPostNointegerMax images returned per post (min 0, max 20, default 5).3
mediaOnlyNobooleanOnly return posts with at least one image (default false).false
rateLimitDelayNointegerBase delay in seconds between page fetches, jittered (min 0, max 60, default 1).1
fetchRetriesNointegerRetries per request before giving up on it (min 0, max 10, default 3).3
proxyConfigurationNoobjectApify 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.

  1. 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 that document and video detection is best-effort HTML-marker matching, while text, image, and article are reliably detected (see the format section above).
  2. Media-presence filtering (mediaOnly) β€” a blunter version of format filtering: true returns 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.
  3. 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.
  4. 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 restrictive postTypes filter combined with a high maxPosts can 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?

ScraperWhat it extracts
LinkedIn Search Jobs Scraper With Advanced Search FiltersLinkedIn job listings, narrowed by workplace type, experience level, employment type, date posted, and salary band
Facebook Group Posts And Details & Contact Leads ScraperFacebook group posts, group profile details, and member contact leads
Threads Search Post ScraperThreads posts by URL, post ID, or search phrase, with engagement and mentions
Twitter X Tweets Scraper Scraper By Keyword & HashtagX (Twitter) posts by keyword or hashtag with typed engagement filters
TikTok Data Scraper β€” Video, Hashtag & Sound PerformanceTikTok 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 ApifyClient
client = 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.

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.