LinkedIn Batch Profile Posts Scraper [NO COOKIES] ✅ avatar

LinkedIn Batch Profile Posts Scraper [NO COOKIES] ✅

Pricing

from $5.50 / 1,000 results

Go to Apify Store
LinkedIn Batch Profile Posts Scraper [NO COOKIES] ✅

LinkedIn Batch Profile Posts Scraper [NO COOKIES] ✅

Scrape LinkedIn posts from any public profile. Extract post text, reactions, comments, media, and author info in bulk. Supports up to 1,000 profiles per run via the Harvest API.

Pricing

from $5.50 / 1,000 results

Rating

5.0

(1)

Developer

Unseen User

Unseen User

Maintained by Community

Actor stats

2

Bookmarked

7

Total users

4

Monthly active users

4 days ago

Last modified

Share

LinkedIn Profile Posts Scraper

Scrape recent posts from any public LinkedIn profile — post text, engagement stats broken down by reaction type, media attachments, and author details. Process up to 1,000 profiles in a single run with no LinkedIn account required.

Why use LinkedIn Profile Posts Scraper?

  • No login required — No cookies, no credentials, no risk to your LinkedIn account.
  • Batch processing — Feed in 1 profile or 1,000. The actor processes 5 profiles concurrently and handles pagination and rate limiting automatically.
  • Structured data — Every post comes back with clean, typed JSON including reaction breakdowns, media classification, and author metadata.
  • Time filtering — Only pull posts from the last 24 hours, week, month, 3 months, 6 months, or year.

Use cases

Use caseHow
Competitor monitoringTrack competitor posting frequency and engagement over time
Content researchAnalyze top-performing posts in your niche to inform your own strategy
Influencer analysisStudy thought leaders' posting patterns and audience engagement
Lead generationMonitor prospect activity to find conversation starters
Brand trackingKeep tabs on your team's LinkedIn presence and reach
Dataset buildingCollect posts at scale for NLP research or AI model training

Input examples

Minimal — scrape one profile with defaults

{
"profileUrls": ["satyanadella"]
}

Standard — multiple profiles with time filter

{
"profileUrls": [
"satyanadella",
"williamhgates",
"https://www.linkedin.com/in/jeffweiner08"
],
"totalPostsPerProfile": 25,
"postedLimit": "month"
}

Full options — clean output with all filters

{
"profileUrls": [
"satyanadella",
"williamhgates",
"raborrego",
"daborrego"
],
"totalPostsPerProfile": 50,
"postedLimit": "3months",
"removeEmptyFields": true
}

Input parameters

ParameterTypeRequiredDefaultDescription
profileUrlsstring[]YesLinkedIn usernames or full profile URLs (e.g. satyanadella or https://www.linkedin.com/in/satyanadella)
totalPostsPerProfileintegerNo20Posts to collect per profile (1–100)
postedLimitstringNoNo limitTime filter: 24h, week, month, 3months, 6months, year
removeEmptyFieldsbooleanNofalseStrip null and empty values from output

Output example

Each dataset item represents one profile with its scraped posts:

{
"profileUsername": "satyanadella",
"posts": [
{
"posted_at": "2 days ago",
"posted_date": "2025-03-15T14:32:00.000Z",
"text": "Thrilled to see the progress our teams are making with AI across every layer of the tech stack. From infrastructure to applications, we're empowering every developer to build with AI.",
"url": "https://www.linkedin.com/feed/update/urn:li:activity:7297410395815849984",
"author": {
"first_name": "Satya",
"last_name": "Nadella",
"headline": "Chairman and CEO at Microsoft",
"profile_url": "https://www.linkedin.com/in/satyanadella",
"profile_picture": "https://media.licdn.com/dms/image/v2/C5603AQHv..."
},
"stats": {
"total_reactions": 18743,
"likes": 14200,
"appreciations": 1850,
"empathy": 1120,
"interests": 873,
"praises": 700,
"comments": 492,
"reposts": 217
},
"media": {
"type": "article",
"url": "https://blogs.microsoft.com/blog/2025/ai-update",
"thumbnail": "https://media.licdn.com/dms/image/v2/article-cover..."
}
},
{
"posted_at": "1 week ago",
"posted_date": "2025-03-10T09:15:00.000Z",
"text": "Great conversation with students at the University of Chicago about how technology can amplify human capability rather than replace it.",
"url": "https://www.linkedin.com/feed/update/urn:li:activity:7295128371054936064",
"author": {
"first_name": "Satya",
"last_name": "Nadella",
"headline": "Chairman and CEO at Microsoft",
"profile_url": "https://www.linkedin.com/in/satyanadella",
"profile_picture": "https://media.licdn.com/dms/image/v2/C5603AQHv..."
},
"stats": {
"total_reactions": 9321,
"likes": 7500,
"appreciations": 620,
"empathy": 450,
"interests": 351,
"praises": 400,
"comments": 287,
"reposts": 103
},
"media": {
"type": "image",
"url": "https://media.licdn.com/dms/image/v2/post-image...",
"thumbnail": null
}
},
{
"posted_at": "2 weeks ago",
"posted_date": "2025-03-03T11:45:00.000Z",
"text": "Sharing our annual report on responsible AI practices. Transparency and accountability are not optional — they're foundational.",
"url": "https://www.linkedin.com/feed/update/urn:li:activity:7293005518910062592",
"author": {
"first_name": "Satya",
"last_name": "Nadella",
"headline": "Chairman and CEO at Microsoft",
"profile_url": "https://www.linkedin.com/in/satyanadella",
"profile_picture": "https://media.licdn.com/dms/image/v2/C5603AQHv..."
},
"stats": {
"total_reactions": 12087,
"likes": 9400,
"appreciations": 980,
"empathy": 720,
"interests": 587,
"praises": 400,
"comments": 341,
"reposts": 189
},
"media": {
"type": "document",
"url": "https://media.licdn.com/dms/document/v2/responsible-ai-report.pdf",
"thumbnail": "https://media.licdn.com/dms/image/v2/document-cover..."
}
}
],
"metadata": {
"profile_url": "https://www.linkedin.com/in/satyanadella",
"total_posts_scraped": 3
}
}

Output fields reference

FieldTypeDescription
profileUsernamestringThe LinkedIn username that was scraped
postsarrayArray of post objects
posts[].posted_atstringRelative time since posted (e.g. "2 days ago", "1 week ago")
posts[].posted_datestringAbsolute date/time the post was published (ISO 8601, e.g. "2025-03-15T14:32:00.000Z")
posts[].textstringFull text content of the post
posts[].urlstringDirect permalink to the post on LinkedIn
posts[].author.first_namestringAuthor's first name
posts[].author.last_namestringAuthor's last name
posts[].author.headlinestringAuthor's LinkedIn headline
posts[].author.profile_urlstringAuthor's LinkedIn profile URL
posts[].author.profile_picturestringAuthor's profile photo URL
posts[].stats.total_reactionsintegerTotal reaction count across all types
posts[].stats.likesintegerNumber of Like reactions
posts[].stats.appreciationsintegerNumber of Appreciation reactions
posts[].stats.empathyintegerNumber of Empathy (Love) reactions
posts[].stats.interestsintegerNumber of Interest (Curious) reactions
posts[].stats.praisesintegerNumber of Praise (Celebrate) reactions
posts[].stats.commentsintegerNumber of comments
posts[].stats.repostsintegerNumber of reposts/shares
posts[].mediaobject/nullAttached media, or null for text-only posts
posts[].media.typestringMedia type: article, image, or document
posts[].media.urlstringURL of the media content
posts[].media.thumbnailstring/nullThumbnail image URL (if available)
metadata.profile_urlstringFull LinkedIn profile URL
metadata.total_posts_scrapedintegerNumber of posts collected for this profile

Error output

When a profile cannot be scraped (invalid username, private profile, API error), the actor logs the error and continues with remaining profiles:

{
"profileUsername": "nonexistent-user-12345",
"posts": [],
"metadata": {
"error": "scrape_failed",
"message": "Profile not found",
"profile_url": "https://www.linkedin.com/in/nonexistent-user-12345",
"total_posts_scraped": 0
}
}

How to use the API

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('YOUR_ACTOR_ID').call({
profileUrls: ['satyanadella', 'williamhgates'],
totalPostsPerProfile: 20,
postedLimit: 'month',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) {
console.log(`${item.profileUsername}: ${item.posts.length} posts`);
for (const post of item.posts) {
console.log(` - [${post.stats.total_reactions} reactions] ${post.text?.slice(0, 80)}...`);
}
}

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("YOUR_ACTOR_ID").call(run_input={
"profileUrls": ["satyanadella", "williamhgates"],
"totalPostsPerProfile": 20,
"postedLimit": "month",
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
for item in items:
print(f"{item['profileUsername']}: {len(item['posts'])} posts")
for post in item["posts"]:
reactions = post["stats"]["total_reactions"]
text = (post["text"] or "")[:80]
print(f" - [{reactions} reactions] {text}...")

cURL

# Start a run
curl -X POST "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"profileUrls": ["satyanadella"],
"totalPostsPerProfile": 10
}'
# Fetch results (use the defaultDatasetId from the run response)
curl "https://api.apify.com/v2/datasets/DATASET_ID/items?format=json" \
-H "Authorization: Bearer YOUR_API_TOKEN"

Integrations

Use Apify integrations to connect this actor to your workflow:

  • Google Sheets — Auto-export posts to a spreadsheet for analysis and reporting.
  • Slack — Get notified when scraping completes or when high-engagement posts are found.
  • Zapier — Trigger downstream workflows with scraped data.
  • Make (Integromat) — Build complex automation pipelines.
  • Google Drive — Save datasets as JSON or CSV files to Drive.
  • Webhook — Send data to any HTTP endpoint when a run finishes.

Tips

  • Usernames are simpler — Pass satyanadella instead of the full URL. Both work, but usernames are less error-prone.
  • Use time filters — Setting postedLimit to month or week speeds up scraping and avoids pulling stale content.
  • Enable removeEmptyFields — Great for cleaner exports, especially when piping into Google Sheets or databases.
  • Schedule runs — Use Apify Schedules to automatically scrape profiles daily, weekly, or on any cron schedule.
  • Check metadata — The total_posts_scraped field tells you exactly how many posts were found; compare against totalPostsPerProfile to know if more exist.

Limitations

  • Only public LinkedIn profiles can be scraped.
  • Maximum 100 posts per profile per run.
  • Maximum 1,000 profiles per run.
  • Engagement stats are point-in-time snapshots — they will differ if you scrape the same post later.
  • Video posts are not currently extracted as a separate media type.

Disclaimer

This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by LinkedIn Corporation. LinkedIn is a registered trademark of LinkedIn Corporation. Use of this actor must comply with LinkedIn's Terms of Service and applicable data privacy regulations.