---
title: "LinkedIn post scraper"
description: "Scrape public LinkedIn posts as JSON: text, publish date, reactions, comments, video and author. One API request from Python, Node.js, the CLI or MCP."
canonical: https://www.zenrows.com/scrape/linkedin-posts
updated: 2026-10-20
---

# LinkedIn post scraper

The Zenrows LinkedIn post scraper turns a public LinkedIn post URL into JSON: post text, publish date, activity URN, reaction count, comment count, visible comments, author name, headline and follower count, video URL, duration and transcript. Fetch in Adaptive Stealth Mode opens the post as a logged-out visitor sees it, and Extract returns the fields. Run it from an API call, the CLI or an AI agent.

- Site: linkedin.com
- Returns: Post text, dates, reactions, comments and media

## Run it: one LinkedIn post in, JSON out

```json Input
{
  "url": "https://www.linkedin.com/posts/williamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV",
  "mode": "auto",
  "extract": "auto"
}
```

```json Output
{
  "post": {
    "activity_urn": "urn:li:activity:7518110626762768384",
    "canonical_url": "https://www.linkedin.com/posts/williamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV",
    "date_published": "2026-10-20T00:47:33.159Z",
    "body": "Some of the fuel powering future flights could start with algae. A Breakthrough Energy company called Phykion is developing highly productive, oil-rich algae to use as sustainable aviation fuel…"
  },
  "engagement": {
    "reaction_count": 207,
    "comment_count": 33
  },
  "author": {
    "name": "Bill Gates",
    "headline": "Chair, Gates Foundation and Founder, Breakthrough Energy",
    "follower_count": 40736493,
    "post_count": 1827,
    "article_count": 295,
    "profile_url": "https://www.linkedin.com/in/williamhgates?trk=public_post_follow-view-profile"
  },
  "media": {
    "duration": "PT1M38S",
    "width": 1280,
    "height": 720,
    "embed_url": "https://www.linkedin.com/feed/update/urn:li:activity:7518110626762768384"
  },
  "comments": [
    {
      "date_published": "2026-10-20T00:54:57.656Z",
      "like_count": null,
      "text": "What interests me is whether the algae can be grown where the fuel will actually be produced…"
    }
  ]
}
```

Request and output of a live call to a public LinkedIn post on Oct 20, 2026, trimmed for length. Commenter names and profile links are left out of this sample.

## What data can you scrape from LinkedIn posts?

A single post URL returns the post, its engagement, the author card, any video and the comments LinkedIn shows logged-out visitors. Posts also appear in bulk inside profile and company pages, with fewer fields per post.

| Field | What it holds | Example |
|---|---|---|
| `post.body` | The post text | `Some of the fuel powering future flights…` |
| `post.date_published` | Publish time in ISO 8601, UTC | `2026-10-20T00:47:33.159Z` |
| `post.activity_urn` | LinkedIn's unique ID for the post | `urn:li:activity:7518110626762768384` |
| `post.canonical_url` | The clean post URL | `https://www.linkedin.com/posts/williamhgates_…` |
| `post.headline` | The page title LinkedIn sets: start of the text, author and comment count | `Some of the fuel powering future flights… Bill Gates…` |
| `post.transcript` | Auto transcript of the post's video | `Of all the challenges in climate change…` |
| `engagement.reaction_count` | All reactions on the post | `207` |
| `engagement.comment_count` | Comments on the post | `33` |
| `author.name` | Who posted it | `Bill Gates` |
| `author.headline` | The author's headline | `Chair, Gates Foundation and Founder, Breakthrough Energy` |
| `author.follower_count` | The author's followers | `40736493` |
| `media.duration` | Video length in ISO 8601 | `PT1M38S` |
| `media.content_url` | Direct link to the video file | `https://dms.licdn.com/playlist/vid/v2/…` |
| `comments[]` | Visible comments with text, time and likes | `{ "like_count": 1, … }` |
| `related_posts[]` | Articles by the same author linked under the post | `{ "title": "For an affordable climate win, look to the sky", … }` |
| `posts[]` (profile or company page) | Recent posts with text and like or reaction counts | `{ "like_count": 185, … }` |

## How to scrape LinkedIn posts with Zenrows

1. **Create a free Zenrows account** and copy your API key from the dashboard.
2. **Get the post URL.** Public posts live at `https://www.linkedin.com/posts/<author>_<slug>-activity-<id>-<code>`. Use "Copy link to post" in LinkedIn, or take `post_url` from a profile's activity list.
3. **Send it with the default configuration**: Adaptive Stealth Mode to open the post and Extract to return the fields. No country is needed.
4. **Read `parsed`.** Store the post under `activity_urn`, which never changes, and keep `engagement` with the date you read it, since the counts grow.
5. **Run your post list in Batch**, and run it again later to track how engagement changes.

```python Python
# pip install requests
import requests

params = {
    "apikey": "YOUR_ZENROWS_API_KEY",
    "url": "https://www.linkedin.com/posts/williamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV",
    "mode": "auto",      # Adaptive Stealth Mode
    "extract": "auto",   # structured JSON
}
response = requests.get("https://api.zenrows.com/v1/", params=params, timeout=180)
response.raise_for_status()

parsed = response.json()["parsed"]
post, stats = parsed["post"], parsed["engagement"]
print(post["activity_urn"], post["date_published"])
print(stats["reaction_count"], "reactions,", stats["comment_count"], "comments")
for comment in parsed.get("comments", []):
    print("-", comment["date_published"], comment["text"][:80])
```

```javascript Node.js
// Node 18+ (built-in fetch)
const params = new URLSearchParams({
  apikey: "YOUR_ZENROWS_API_KEY",
  url: "https://www.linkedin.com/posts/williamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV",
  mode: "auto",
  extract: "auto",
});

const response = await fetch(`https://api.zenrows.com/v1/?${params}`, {
  signal: AbortSignal.timeout(180_000),
});
if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);

const { parsed } = await response.json();
console.log(parsed.author.name, parsed.post.date_published, parsed.engagement);
```

```bash cURL
curl "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fwww.linkedin.com%2Fposts%2Fwilliamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV&mode=auto&extract=auto"

# Only the fields you need
curl "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fwww.linkedin.com%2Fposts%2Fwilliamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV&mode=auto&extract=auto&extract_fields=post.body%2Cpost.date_published%2Cengagement.reaction_count%2Cengagement.comment_count"
```

```python Python SDK
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_ZENROWS_API_KEY")

# 1. Read a profile's recent activity, 2. open each post for the full record
profile = client.get("https://www.linkedin.com/in/williamhgates",
                     params={"mode": "auto", "extract": "auto"}).json()["parsed"]
for item in profile["posts"]:
    if not item.get("post_url"):
        continue
    post = client.get(item["post_url"], params={"mode": "auto", "extract": "auto"}).json()["parsed"]
    print(post["post"]["date_published"], post["engagement"]["reaction_count"], post["post"]["body"][:60])
```

## Input

The scraper takes one public post URL per request, or a profile or company page URL when you want the recent posts listed there. A Batch job applies the same options to every URL.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `url` | string | required | A public post (`/posts/…-activity-<id>-…`), or a profile (`/in/<vanity>`) or company page (`/company/<slug>`) for its recent posts |
| `mode` | string | `auto` | Adaptive Stealth Mode: starts with the lightest setup and adds rendering and protected-site handling only when the page needs them |
| `extract` | string | `auto` | Returns the post as JSON in `parsed`, next to the raw `html` |
| `extract_fields` | string | all fields | Comma-separated paths to keep, such as `post.body,engagement,author.name` |
| `proxy_country` | string | any | Two-letter country code, optional. Set it when you want the request to come from a specific country |
| `wait_for` | string | none | A CSS selector to wait for before the page is read |

```json Batch input
{
  "type": "regular",
  "status": "closed",
  "zenrows_params": {
    "mode": "auto",
    "extract": "auto"
  },
  "tasks": [
    { "url": "https://www.linkedin.com/posts/williamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV", "external_id": "7518110626762768384" },
    { "url": "https://www.linkedin.com/posts/williamhgates_made-in-africa-new-measles-rapid-diagnostic-activity-7517390588447621121-fbmC", "external_id": "7517390588447621121" },
    { "url": "https://www.linkedin.com/company/microsoft", "external_id": "microsoft-recent-posts" }
  ]
}
```

## Output

Every response is JSON with two keys: `html`, the page as LinkedIn served it, and `parsed`, the structured record. A post page returns the full record; a profile or company page returns a lighter list of recent posts. All three samples are trimmed live outputs.

```json Post page
{
  "author": {
    "article_count": 295,
    "avatar_url": "https://media.licdn.com/dms/image/v2/D5603AQF-RYZP55jmXA/profile-displayphoto-shrink_400_400/…",
    "follower_count": 40736493,
    "headline": "Chair, Gates Foundation and Founder, Breakthrough Energy",
    "name": "Bill Gates",
    "post_count": 1827,
    "profile_url": "https://www.linkedin.com/in/williamhgates?trk=public_post_follow-view-profile"
  },
  "comments": [
    {
      "date_published": "2026-10-20T00:52:34.230Z",
      "like_count": 1,
      "text": "La vraie innovation naît quand on stabilise le cadre sous pression pour penser plus loin…"
    }
  ],
  "engagement": {
    "comment_count": 33,
    "reaction_count": 207
  },
  "media": {
    "captions_url": "https://dms.licdn.com/playlist/vid/v2/D4E05AQH3Igy1Xn-SoQ/video-auto-caption-webvtt-acs-singleton/…",
    "content_url": "https://dms.licdn.com/playlist/vid/v2/D4E05AQH3Igy1Xn-SoQ/mp4-640p-30fp-crf28/…",
    "duration": "PT1M38S",
    "embed_url": "https://www.linkedin.com/feed/update/urn:li:activity:7518110626762768384",
    "height": 720,
    "thumbnail_url": "https://media.licdn.com/dms/image/v2/D4E05AQH3Igy1Xn-SoQ/videocover-high/…",
    "width": 1280
  },
  "post": {
    "activity_urn": "urn:li:activity:7518110626762768384",
    "body": "Some of the fuel powering future flights could start with algae…",
    "canonical_url": "https://www.linkedin.com/posts/williamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV",
    "date_published": "2026-10-20T00:47:33.159Z",
    "headline": "Some of the fuel powering future flights could start with algae… | Bill Gates | 33 comments",
    "transcript": "Transcript\n Of all the challenges in climate change, getting rid of airplane emissions is one of the most difficult…"
  },
  "related_posts": [
    {
      "author_name": "Bill Gates",
      "thumbnail_url": null,
      "title": "For an affordable climate win, look to the sky",
      "url": "https://www.linkedin.com/pulse/affordable-climate-win-look-sky-bill-gates-eoj7e?trk=public_post"
    }
  ]
}
```

```json Profile activity
{
  "posts": [
    {
      "date_published": null,
      "like_count": 1004,
      "post_url": "https://www.linkedin.com/posts/williamhgates_we-can-drastically-cut-aviations-climate-activity-7517635773937025025-Qs-n",
      "text": "Contrails.org is doing amazing research and developing software (including a really cool, interactive map) to help airlines avoid routes that create warming contrails…"
    },
    {
      "date_published": null,
      "like_count": 1769,
      "post_url": "https://www.linkedin.com/posts/williamhgates_smallpox-was-once-one-of-the-deadliest-diseases-activity-7516257218011426816-xE7v",
      "text": "Smallpox was once one of the deadliest diseases on earth, killing every three in ten people it infected…"
    }
  ]
}
```

```json Company page posts
{
  "posts": [
    {
      "comment_count": 768,
      "is_repost": null,
      "reaction_count": 19469,
      "text": "Today we are announcing our biggest bet yet on our own silicon…"
    },
    {
      "comment_count": 24,
      "is_repost": null,
      "reaction_count": 337,
      "text": "A new generation of Surface is here.\nBuilt for creators, developers, AI builders, and the people pushing technology forward…"
    }
  ]
}
```

The profile list carries `post_url` for each post, so it is the fastest way to find a member's posts. Open each URL to get the date, comments and full engagement.

## Scrape LinkedIn posts from your coding agent

Claude Code, Cursor, Codex and any MCP client can read LinkedIn posts from a prompt and summarize the conversation under them.

The agent sends the same Fetch and Extract request shown above and reads the same JSON. Connect the Zenrows MCP server once, or install the CLI and let the agent call it in the terminal.

```bash Connect the MCP server (Claude Code)
claude mcp add zenrows -e ZENROWS_API_KEY=YOUR_ZENROWS_API_KEY -- npx -y @zenrows/mcp
```

```json MCP config (Cursor, Claude Desktop, Windsurf)
{
  "mcpServers": {
    "zenrows": {
      "command": "npx",
      "args": ["-y", "@zenrows/mcp"],
      "env": { "ZENROWS_API_KEY": "YOUR_ZENROWS_API_KEY" }
    }
  }
}
```

```bash Or run the CLI
npx -y @zenrows/cli init
zenrows extract "https://www.linkedin.com/posts/williamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV"
```

```text Then ask your agent
Use Zenrows to read this LinkedIn post. Give me the publish date,
reactions and comments, then group the visible comments into the main
questions people are asking:
https://www.linkedin.com/posts/williamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV
```

## Scrape LinkedIn posts at scale with Batch and Crawl

**Batch** runs a list of post URLs as one job, in parallel, with your own ID on each result. Use the activity number as the ID and rerun the same list a day and a week later to chart how reactions and comments grow.

**Crawl** finds post URLs on a profile or company page. Start it on the page, keep the links that contain `/posts/`, and it returns every post page it reaches. Send that list to Batch with Extract for the structured record of each.

```bash Batch (cURL)
curl -X POST "https://async.api.zenrows.com/v1/jobs" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "regular",
    "status": "closed",
    "zenrows_params": { "mode": "auto", "extract": "auto" },
    "tasks": [
      { "url": "https://www.linkedin.com/posts/williamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV", "external_id": "7518110626762768384" },
      { "url": "https://www.linkedin.com/posts/williamhgates_made-in-africa-new-measles-rapid-diagnostic-activity-7517390588447621121-fbmC", "external_id": "7517390588447621121" }
    ]
  }'

# Read the results when the job finishes
curl "https://async.api.zenrows.com/v1/jobs/JOB_ID/results?status=successful" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY"
```

```bash Batch (CLI)
# posts.jsonl: one {"url": "...", "external_id": "...", "extract": "auto"} per line
zenrows batch create posts.jsonl --wait
zenrows batch results <job-id> --out linkedin-posts.jsonl
```

```bash Crawl (cURL)
curl -X POST "https://api.zenrows.com/v1/crawls" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.linkedin.com/in/williamhgates",
    "depth": 1,
    "max_pages": 30,
    "include_patterns": ["/posts/"]
  }'
```

**Scheduled jobs** run the same Batch job on a timetable, on Zenrows' side: every few hours, once a day, at set times on chosen days, or once at a future date. Each run keeps its own results, a webhook can tell your app when a run finishes, and you can pause or resume the schedule at any time, with no cron server to keep alive.

```bash Scheduled job (cURL)
# Runs every day on Zenrows' side; each run keeps its own results
curl -X POST "https://async.api.zenrows.com/v1/jobs" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "type": "scheduled",
      "status": "closed",
      "schedule": {
        "rate": {
          "every": 1,
          "unit": "day"
        }
      },
      "zenrows_params": {
        "mode": "auto",
        "extract": "auto"
      },
      "tasks": [
        {
          "url": "https://www.linkedin.com/posts/williamhgates_some-of-the-fuel-powering-future-flights-activity-7518110626762768384-mNGV",
          "external_id": "linkedin-posts"
        }
      ]
    }'

# Or at set times: "schedule": { "calendar": { "times_of_day": ["09:00"],
#   "cadence": { "weekly": { "days": ["mon", "thu"] } } }, "timezone": "Europe/Madrid" }
```

## What teams do with LinkedIn post data

| Use case | Data they pull | Who runs it |
|---|---|---|
| Executive and competitor content tracking | Post text, date and reactions from a list of company pages and leaders | Marketing and comms teams |
| Campaign and launch measurement | Reactions and comment counts on announcement posts, read on a schedule | Brand and social media teams |
| Audience questions and sentiment | Visible comment text and timestamps under posts on a topic | Product marketing and research teams |
| B2B influencer research | Author headline, follower count, post count and engagement per post | Partnerships and influencer teams |
| Video content analysis | Video duration, transcript and caption file of video posts | Content strategy teams |
| AI briefings | Post body and transcript as clean text for a summary or a RAG index | AI and data teams |

## Tips for scraping LinkedIn posts

- **Key on the activity number.** `post.activity_urn` (`urn:li:activity:7518110626762768384`) is unique and stable. The number also appears in the post URL and in `media.embed_url`.
- **Date every engagement read.** Reactions and comments change for days after a post goes up. Store `engagement` with the time you read it, and compare runs to see momentum.
- **Find posts through profiles and company pages.** A profile's `posts[]` returns `post_url` for each recent item. Company pages return text, reactions and comment counts per post, which is enough for a quick engagement table.
- **Tell posts from reposts.** In a profile's activity list, the account name at the start of `post_url` shows who wrote the post. Company pages also carry `is_repost`.
- **Use the transcript for video posts.** `post.transcript` holds the video's spoken text, which is often more informative than the caption.
- **Compare visible comments with the total.** The page shows a subset of comments to logged-out visitors (9 of 33 on the sample). Use `engagement.comment_count` for the total and the `comments[]` list as a sample of the discussion.

## Frequently asked questions

### Is it legal to scrape LinkedIn posts?

Public posts are visible to anyone, and reading them for research and media monitoring is common practice. Posts and comments contain personal data, protected by the GDPR in the EU and UK and the CCPA in California, so collect only what you have a lawful basis for and drop commenter details you don't need. LinkedIn's User Agreement restricts automated collection, so check its terms for your use case and ask your lawyer if you are unsure.

### Is there an official LinkedIn posts API?

LinkedIn's Posts API and Community Management API let approved apps publish and read posts for the organizations or members that authorized them. They require access approval and do not return other people's public posts on request. To read any public post, teams use a scraper.

### What LinkedIn posts can I scrape?

Public posts from members and company pages, at their /posts/ URLs, plus the recent-posts lists on public profiles and company pages. Posts shared only with connections, group posts and anything behind a login are not public and are not collected.

### Can I scrape comments on a LinkedIn post?

Yes. A post page returns the comments LinkedIn shows logged-out visitors, each with text, time and likes, next to the total comment count in engagement .

### Do I need a LinkedIn account to scrape posts?

No. Zenrows opens each post as a logged-out visitor, so you never share an account, a cookie or a password.

### How do I scrape LinkedIn posts with Python?

Send a GET request to https://api.zenrows.com/v1/ with your API key, the post URL, Adaptive Stealth Mode and Extract turned on, as in the Python example above. The parsed key holds the post, engagement, author and comments as a dictionary. The zenrows package on PyPI wraps the same request.

### Can AI agents scrape LinkedIn posts with Zenrows?

Yes. Connect the Zenrows MCP server to Claude, Cursor, Codex or any MCP client, or give your agent the Zenrows CLI. Paste post URLs or a profile and ask your question; the agent calls Fetch and Extract for you.

### Can I scrape LinkedIn on a schedule?

Yes. Create a scheduled Batch job with your LinkedIn URLs and the same settings as a single request, and Zenrows runs it on its side: every few hours, once a day, at set times on chosen days, or once at a future date. Each run keeps its own results, a webhook can notify your app when a run finishes, and the schedule can be paused or resumed at any time.

### Which integrations work with the LinkedIn post scraper?

Zenrows works with n8n, Make, Zapier, Clay, Dify, LangChain, LlamaIndex, CrewAI and Mastra, plus the Python, Node.js and Go SDKs and any HTTP client. A scheduled n8n or Make run can post new company updates and their engagement to Slack or a sheet. See the integrations page for the full list.

### What format does the data come in?

JSON by default, with the structured post in parsed and the original page in html . You can also ask for Markdown or plain text, which suits post and transcript text that goes to an LLM.

## More LinkedIn scrapers

- [LinkedIn scraper](https://www.zenrows.com/scrape/linkedin.md)
- [LinkedIn jobs scraper](https://www.zenrows.com/scrape/linkedin-jobs.md)
- [LinkedIn profile scraper](https://www.zenrows.com/scrape/linkedin-profile.md)

All scrapers: https://www.zenrows.com/scrape. Start free: https://app.zenrows.com/register. Docs: https://docs.zenrows.com
