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

15

Total users

9

Monthly active users

6 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 row represents a single post, with profile info included on every row for easy CSV/spreadsheet export:

{
"profileUsername": "satyanadella",
"profile_url": "https://www.linkedin.com/in/satyanadella",
"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..."
}
}

Output fields reference

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

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",
"profile_url": "https://www.linkedin.com/in/nonexistent-user-12345",
"error": "scrape_failed",
"error_message": "Profile not found"
}

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 post of items) {
console.log(`${post.profileUsername}: ${post.text?.slice(0, 80)}...`);
if (post.stats) {
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 post in items:
reactions = post.get("stats", {}).get("total_reactions", 0)
text = (post.get("text") or "")[:80]
print(f"[{post['profileUsername']}] [{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.
  • Filter by profile — Since each row is a single post, use profileUsername to group or filter results by profile.

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.