# Facebook Comments Scraper (`apt_marble/facebook-comments-scraper`) Actor

Collect the public comments on any Facebook post: author, full text, date, the like figure Facebook displays and the reply count, one clean row each. Works on posts, photos and videos, needs no account, and tells you plainly how many comments are publicly reachable.

- **URL**: https://apify.com/apt\_marble/facebook-comments-scraper.md
- **Developed by:** [Hamza](https://apify.com/apt_marble) (community)
- **Categories:** Social media, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 comment scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Facebook Comments Scraper

Give it a link to any public Facebook post and get the comments back as clean
rows: who wrote each one, the full text, when it was posted, the like figure
Facebook shows next to it and how many replies it has. It works on ordinary
posts, photo posts, videos and permalinks, and it needs no Facebook account of
any kind.

Read the honest ceiling first: **Facebook lets a signed-out visitor reach roughly
the first 45 comments of a post, no matter how many the post has.** Everything
below is built around telling you that plainly instead of quietly returning less
than you expected.

### What you can do with it

- **Read the room on a campaign post** — pull the comments on your own or a
  client's post and see what people actually said, not just how many reacted.
- **Mine competitor posts for complaints and feature wishes** that keep coming up, and
  turn them into product or content ideas.
- **Track sentiment on a launch announcement** by collecting the comments on the
  announcement post over several days.
- **Collect quotes and testimonials** people leave publicly under a brand's
  posts, with the author name and the date attached.
- **Build a labelled text set** for classification or sentiment work from real,
  public, dated comments.

### What you get

One row per comment. Abridged real example:

```
{
  "postId": "1549668713863782",
  "commentId": "1302275481768604",
  "authorName": "Simon Turner",
  "authorId": "100000017317209",
  "authorIsOpaque": false,
  "text": "Is it where they make pool reflection liner paint?!",
  "publishedAt": "2026-08-01T19:07:20.000Z",
  "likesText": "18",
  "replyCount": 1,
  "depth": 0,
  "attachmentCount": 0,
  "postDeclaredComments": 102,
  "availability": "OK",
  "sourceUrl": "https://www.facebook.com/bbcnews/posts/pfbid02Ahoi9Dz...",
  "scrapedAt": "2026-08-01T19:21:44.881Z"
}
```

### Input reference

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| **Post links** | list of text | one example post | The posts whose comments you want. Open a post, video or photo on Facebook and copy the link from your browser. Required. |
| **Comments per post** | whole number 1–50 | `30` | The most comments to collect from each post. Because of the ceiling described below, a higher number does not always mean more rows. |
| **Browse from** | choice | United States | The country to browse from. Some posts are shown differently depending on where the visitor is. |
| **Posts at a time** | whole number 1–8 | `4` | How many posts to work on simultaneously. Four is the sweet spot; higher is not faster. |

Anything that is not a post link — a Page link, a home page link, a link from
another site — is skipped with a message saying why, and the run continues.

### Output fields

| Field | Description |
| --- | --- |
| `postId` | The post the comment belongs to. |
| `commentId` | Facebook's own identifier for the comment. |
| `authorName` | The commenter's display name. |
| `authorId` | The commenter's identifier. |
| `authorIsOpaque` | `true` when Facebook published a one-way code instead of a real profile number — 8 of the 10 commenters on the post we sampled. Those values identify nobody and cannot be matched against other data. `null` when no identifier was published at all. |
| `authorUrl` | The commenter's profile link, where Facebook publishes one. |
| `text` | The full comment text. |
| `publishedAt` | When the comment was posted, in ISO 8601. |
| `likesText` | The like figure **exactly as Facebook displays it** — `"0"`, `"18"`, `"1.7K"`. It is text, not a number: see the limits. |
| `replyCount` | How many replies the comment has. |
| `depth` | `0` for a top-level comment. |
| `attachmentCount` | How many pictures or stickers are attached to the comment. |
| `postDeclaredComments` | The comment count Facebook shows on the post itself, so you can see the gap between that and what is publicly reachable. |
| `availability` | `OK` for every row produced. |
| `sourceUrl` | The post the row came from. |
| `scrapedAt` | When the row was collected. |

### Pricing

You pay per comment plus a small one-off charge for each post whose thread had to
be continued beyond what the post shows on arrival:

- **$0.0004 per comment** — $0.40 per 1,000 comments.
- **$0.004 per post** whose thread was continued. Posts whose comments all
  arrived with the post are not charged this.

A run over 100 posts collecting 30 comments each costs about
**$1.20 + $0.40 = $1.60**. Posts that turn out to be unavailable, and posts with
no public comments, produce no rows and cost nothing.

### Limits & what this actor cannot do

- **About 45 comments per post is the public ceiling.** On a post showing 102
  comments, a signed-out visitor could reach 46 of them and then Facebook simply
  stopped — while still claiming more were available. Big posts with thousands of
  comments will therefore yield a small sample, not the lot. `postDeclaredComments`
  on every row shows you the gap. Any product claiming complete public comment
  collection for Facebook is not telling you the truth.
- **Replies are never returned.** Facebook publishes the reply *count* to
  signed-out visitors but not the reply *text*, so `replyCount` is filled in and
  no reply rows exist. Note that the count shown on the post includes replies,
  which is part of why it is so much larger than what can be collected.
- **Comment like figures are text, not numbers.** Facebook shows `1.7K`, not
  `1,700`, and no exact figure is published anywhere on this surface. `likesText`
  keeps what was shown; nothing is converted into a number that was never
  published, so do not sum this column.
- **Many commenter identifiers are one-way codes.** On the post we sampled, 8 of
  the 10 commenters had a one-way code instead of a profile number. The share
  varies from post to post and no fixed proportion is promised, so size any join
  on the `authorIsOpaque` flag on your own rows rather than on an average.
- **Comment ordering is Facebook's, not yours.** Facebook decides which comments
  a signed-out visitor sees and in which order; there is no way to ask for oldest
  first, newest first or most liked.
- **Reels usually return no comments publicly**, even when the reel shows a large
  comment count. Those posts are reported as having none rather than failing.
- **Some posts are not publicly viewable at all.** Posts on Pages or in groups
  that require signing in, and links to posts that no longer exist, are reported
  as unavailable rather than returned empty — and are not charged for.
- **There is no search.** You supply the post links; the actor cannot find posts
  by keyword, topic or Page.
- **Speed depends on the size of the job** and on how quickly Facebook answers on
  the day. No fixed rate is promised.
- **Use the data lawfully.** Facebook's terms prohibit automated collection, and
  comment text and author names are personal data. You are responsible for using
  what you collect in line with the source site's terms and with applicable
  privacy law — including erasure obligations and the rules on profiling.

### FAQ

**Do I need a Facebook account?**
No. Only public comments are collected, and no account is ever involved.

**Does it need my login or any personal details?**
No. There is nothing to connect and nothing to sign in to.

**Can I schedule it?**
Yes. Running the same post daily is a good way to catch comments as they arrive,
since new comments are often the ones publicly reachable.

**Is the data complete?**
No, and no tool can make it so without an account. Facebook stops a signed-out
visitor at roughly 45 comments per post and never returns replies. Every row
carries `postDeclaredComments` so the gap is visible in your own data.

**Why is `likesText` text instead of a number?**
Because Facebook publishes `1.7K` rather than an exact figure. Converting that to
`1700` would invent precision that does not exist.

**I asked for 50 comments and got 46. Why?**
That is the ceiling, not a failure. Facebook stopped returning more.

**What about replies to comments?**
The count is reported; the text is not published to signed-out visitors, so it
cannot be collected.

# Actor input Schema

## `postUrls` (type: `array`):

Links to the Facebook posts whose comments you want. Open a post, video, reel or photo and copy the link from your browser.

## `maxCommentsPerPost` (type: `integer`):

The most comments to collect from each post. Facebook only lets a signed-out visitor reach roughly the first 45 comments of a post, so a higher number does not always mean more rows.

## `country` (type: `string`):

The country to browse from. Some posts are shown differently depending on where the visitor is.

## `concurrency` (type: `integer`):

How many posts to work on at the same time. Four is the sweet spot; higher is not faster and is more likely to be turned away.

## Actor input object example

```json
{
  "postUrls": [
    "https://www.facebook.com/bbcnews/posts/pfbid02Ahoi9DzYPrcsebiwdSZyKpUDUynzbGXv2yxDoT5UooyYpTLdG7rB29GaZSxxtBuXl"
  ],
  "maxCommentsPerPost": 30,
  "country": "us",
  "concurrency": 4
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "postUrls": [
        "https://www.facebook.com/bbcnews/posts/pfbid02Ahoi9DzYPrcsebiwdSZyKpUDUynzbGXv2yxDoT5UooyYpTLdG7rB29GaZSxxtBuXl"
    ],
    "maxCommentsPerPost": 30,
    "country": "us",
    "concurrency": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("apt_marble/facebook-comments-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "postUrls": ["https://www.facebook.com/bbcnews/posts/pfbid02Ahoi9DzYPrcsebiwdSZyKpUDUynzbGXv2yxDoT5UooyYpTLdG7rB29GaZSxxtBuXl"],
    "maxCommentsPerPost": 30,
    "country": "us",
    "concurrency": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("apt_marble/facebook-comments-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "postUrls": [
    "https://www.facebook.com/bbcnews/posts/pfbid02Ahoi9DzYPrcsebiwdSZyKpUDUynzbGXv2yxDoT5UooyYpTLdG7rB29GaZSxxtBuXl"
  ],
  "maxCommentsPerPost": 30,
  "country": "us",
  "concurrency": 4
}' |
apify call apt_marble/facebook-comments-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,apt_marble/facebook-comments-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/qT6gOf69OQBnk9SX8/builds/s0dwkYFbIvhSLs2UH/openapi.json
