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

Extract comments from Facebook posts provided as input URLs. Retrieve comment text, authors, timestamps, reactions, and more. Ideal for social media monitoring, sentiment analysis, and engagement tracking. 🚀

- **URL**: https://apify.com/scraper_one/facebook-comments-scraper.md
- **Developed by:** [Scraper One](https://apify.com/scraper_one) (community)
- **Categories:** Social media, Automation, Developer tools
- **Features:** Limited permissions
- **Stats:** 927 total users, 68 monthly users, 99.8% runs succeeded, 21 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.40 / 1,000 result items

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Facebook Comments Scraper

![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue)

This **Apify Actor** extracts comments from **Facebook posts** provided as input URLs. It retrieves comment text,
authors, timestamps, reactions, and more. This
tool is ideal for **social media monitoring, sentiment analysis, and engagement tracking**. 🚀

***

### Features

- 🔍 Scrape **comments from multiple posts**
- 👥 Extract **author details and profile URLs**
- 📅 Retrieve **timestamps and reactions**
- 🔢 Limit the number of comments per post

### Input Parameters

| Parameter          | Type       | Required | Description                                                                                                                                        |
|--------------------|------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| `postUrls`         | `string[]` | ✅        | Array of Facebook post URLs to extract comments from.                                                                                              |
| `resultsLimit`     | `number`   | ❌        | Maximum number of results per post, including the original post when enabled (optional). If not set, only a few of the first comments will be returned.                                      |
| `commentsSortType` | `string`   | ❌        | Type of comments (sorting) to fetch: `"relevant"` (most relevant), `"newest"` or `"all"`. If omitted, uses the sorting initially selected by Facebook for each post. |
| `includeOriginalPost` | `boolean` | ❌ | If true, the original post will be included as a first reply. False by default. |

### Example Inputs

#### Default sorting

Omit `commentsSortType` to use the sorting initially selected by Facebook for each post.

```json
{
    "postUrls": [
        "https://www.facebook.com/fanpage.TECHART/posts/pfbid0ZYMHCBMGHHQ9W98d9goZ4VpxTeLJSxsZGLfa2V2qbdH6jUyLEUubNTtU7joTi2vVl"
    ],
    "resultsLimit": 50
}
```

#### Newest comments first

Set `commentsSortType` to `"newest"` to request comments sorted from newest to oldest.

```json
{
    "postUrls": [
        "https://www.facebook.com/fanpage.TECHART/posts/pfbid0ZYMHCBMGHHQ9W98d9goZ4VpxTeLJSxsZGLfa2V2qbdH6jUyLEUubNTtU7joTi2vVl"
    ],
    "resultsLimit": 50,
    "commentsSortType": "newest"
}
```

You can also set `commentsSortType` to `"relevant"` for the most relevant comments or `"all"` for all comments, still subject to `resultsLimit`. If Facebook does not offer selectable sorting for a post, the actor uses Facebook's default sorting.

#### Include the original post

```json
{
    "postUrls": [
        "https://www.facebook.com/fanpage.TECHART/posts/pfbid0ZYMHCBMGHHQ9W98d9goZ4VpxTeLJSxsZGLfa2V2qbdH6jUyLEUubNTtU7joTi2vVl"
    ],
    "resultsLimit": 20,
    "includeOriginalPost": true
}
```

The original post counts toward `resultsLimit`: 20 results means the post plus up to 19 comments. If the original post cannot be extracted, the actor continues collecting comments.

### Output Data

The actor returns an array of JSON objects with extracted comments data and, when requested, the original post.

`inputUrl` identifies the original input URL that produced each comment, original post or error record, including share links. Leading and trailing whitespace is trimmed. For comments, `url` is the comment URL returned by Facebook. For the optional original post record, `url` equals the input URL.

**Backward compatibility:** `postUrl` retains its existing value (the input URL). Use `inputUrl` to associate results with input URLs consistently across Facebook Comments Scraper and Facebook Posts Scraper.

`attachments` is included for comments with supported media. Each attachment contains a `type` (`photo`, `gif`, or `sticker`) and a `url`. `commentText` contains only the comment's text and may be absent for media-only comments.

#### Example Output

```json
[
    {
        "inputUrl": "https://www.facebook.com/NFL/posts/pfbid023uiL1TJbp9QxWuCXSR3JamtrXev9LGDNHnpQAuf1dr6kU7Em8hU3oLms5mb4KZQhl",
        "commentText": "George Kittle must've had a word with the GM",
        "attachments": [
            {
                "type": "sticker",
                "url": "https://example.com/sticker.webp"
            }
        ],
        "id": "Y29tbWVudDoxMTg2ODEyNDY5NDgyMjc1XzY2ODE2MzY0NTU0NjI3Mg==",
        "legacyId": 668163645546272,
        "timestamp": 1742045152000,
        "url": "https://www.facebook.com/NFL/posts/pfbid023uiL1TJbp9QxWuCXSR3JamtrXev9LGDNHnpQAuf1dr6kU7Em8hU3oLms5mb4KZQhl?comment_id=668163645546272",
        "author": {
            "id": "pfbid027qk7JdC2FUy2SHN9PQ1uQrPUAwaSaKVCTNFD6KeN9GRfdw7n4C5k3w6naCtYseQZl",
            "profilePictureUrl": "https://scontent.fpoz3-1.fna.fbcdn.net/v/t39.30808-1/484832087_2619507948255427_8811130316462776878_n.jpg?stp=cp6_dst-jpg_s50x50_tt6&_nc_cat=107&ccb=1-7&_nc_sid=e99d92&_nc_ohc=8WugMfDPwGAQ7kNvgFARVYa&_nc_oc=Adk98TB_DjhE7FBLYrhYQSa1s9-iOs0bcnRyTpUO3H0SMbziMMFJu-GYw9xqkuy1ZFE&_nc_zt=24&_nc_ht=scontent.fpoz3-1.fna&_nc_gid=bRJ5zIIdp6dC4pjPIysFaA&oh=00_AYEDOB5Oa9JFPYnAZ2uN6tk-WjfJ34PmbS1pY4e13oWLbw&oe=67E0EC7E",
            "name": "Zack Crouch"
        },
        "postUrl": "https://www.facebook.com/NFL/posts/pfbid023uiL1TJbp9QxWuCXSR3JamtrXev9LGDNHnpQAuf1dr6kU7Em8hU3oLms5mb4KZQhl",
        "reactions": {
            "like": 178,
            "love": 8,
            "haha": 4,
            "support": 1
        },
        "reactionsCount": "191"
    },
    {
        "inputUrl": "https://www.facebook.com/NFL/posts/pfbid023uiL1TJbp9QxWuCXSR3JamtrXev9LGDNHnpQAuf1dr6kU7Em8hU3oLms5mb4KZQhl",
        "commentText": "A photo from the game.",
        "attachments": [
            {
                "type": "photo",
                "url": "https://example.com/comment-photo.jpg"
            }
        ],
        "id": "Y29tbWVudDoxMTg2ODEyNDY5NDgyMjc1XzY2ODE2MzY0NTU0NjI3Mw==",
        "legacyId": 668163645546273,
        "timestamp": 1742045162000,
        "url": "https://www.facebook.com/NFL/posts/pfbid023uiL1TJbp9QxWuCXSR3JamtrXev9LGDNHnpQAuf1dr6kU7Em8hU3oLms5mb4KZQhl?comment_id=668163645546273",
        "author": {
            "id": "100000000000001",
            "profilePictureUrl": "https://example.com/avatar.jpg",
            "name": "Example Author"
        },
        "postUrl": "https://www.facebook.com/NFL/posts/pfbid023uiL1TJbp9QxWuCXSR3JamtrXev9LGDNHnpQAuf1dr6kU7Em8hU3oLms5mb4KZQhl",
        "reactions": {
            "like": 2
        },
        "reactionsCount": "2"
    },
    {
        "inputUrl": "https://www.facebook.com/NFL/posts/pfbid023uiL1TJbp9QxWuCXSR3JamtrXev9LGDNHnpQAuf1dr6kU7Em8hU3oLms5mb4KZQhl",
        "attachments": [
            {
                "type": "gif",
                "url": "https://example.com/animation.gif"
            }
        ],
        "id": "Y29tbWVudDoxMTg2ODEyNDY5NDgyMjc1XzY2ODE2MzY0NTU0NjI3NA==",
        "legacyId": 668163645546274,
        "timestamp": 1742045172000,
        "url": "https://www.facebook.com/NFL/posts/pfbid023uiL1TJbp9QxWuCXSR3JamtrXev9LGDNHnpQAuf1dr6kU7Em8hU3oLms5mb4KZQhl?comment_id=668163645546274",
        "author": {
            "id": "100000000000002",
            "profilePictureUrl": "https://example.com/another-avatar.jpg",
            "name": "Another Example Author"
        },
        "postUrl": "https://www.facebook.com/NFL/posts/pfbid023uiL1TJbp9QxWuCXSR3JamtrXev9LGDNHnpQAuf1dr6kU7Em8hU3oLms5mb4KZQhl",
        "reactions": {
            "like": 1
        },
        "reactionsCount": "1"
    }
]
```

#### URL errors

Errors are saved as separate dataset rows with one of the following codes:

- `INVALID_URL`: invalid or unsupported URL.
- `PAGE_UNAVAILABLE`: content confirmed unavailable.
- `AGE_RESTRICTED`: Facebook showed an 18+ access screen for this URL.

##### Example error record

```json
{
    "inputUrl": "https://www.facebook.com/example/posts/123",
    "error": "PAGE_UNAVAILABLE"
}
```

Successful records do not include `error`. Error rows are not billed as scraped results and do not consume `resultsLimit`; the run initialization charge still applies. The actor continues processing the other input URLs.

##### Example dataset with results and an error record

One complete comment record from a share link and one complete error record for another input:

```json
[
    {
        "inputUrl": "https://www.facebook.com/share/p/example/",
        "commentText": "First example comment.",
        "id": "Y29tbWVudDoxMjNfNDU2",
        "legacyId": 456,
        "timestamp": 1742045152000,
        "url": "https://www.facebook.com/example/posts/123?comment_id=456",
        "author": {
            "id": "100000000000001",
            "profilePictureUrl": "https://example.com/avatar.jpg",
            "name": "Example Author"
        },
        "postUrl": "https://www.facebook.com/share/p/example/",
        "reactions": {
            "like": 2,
            "love": 1
        },
        "reactionsCount": "3"
    },
    {
        "inputUrl": "https://www.facebook.com/example/posts/999",
        "error": "PAGE_UNAVAILABLE"
    }
]
```

Zero comments, disabled comments, login requirements and technical failures do not by themselves mean that a post is unavailable. An accessible post with no comments can return no rows, or just the original post when `includeOriginalPost` is enabled.

### Usage

1. **Create an Apify account** and navigate to the actor.
2. **Configure input parameters** in the Apify UI or via API.
3. **Run the actor** and monitor execution logs.
4. **Download extracted comments** as JSON, CSV, or Excel.

### Limitations & Notes

- Supply individual post, group post, photo, reel, video or share URLs. Profile and group feeds, login, Ads Library and sharing-dialog URLs are unsupported and produce `INVALID_URL` records.
- Duplicate or equivalent post URLs are processed once; results retain the first input URL (with surrounding whitespace trimmed).
- Scraping Facebook data **must comply with their Terms of Service**.
- Avoid excessive scraping to prevent IP bans.
- The accuracy of data depends on Facebook’s page structure and visibility settings.
- Free users can process up to **5 post URLs per run** and retrieve up to **100 results per post URL**, including the original post when enabled.
- Free users are rate-limited to a certain number of actually processed post URLs per day.
- For higher usage limits, upgrade to a [paid Apify plan](https://apify.com/pricing).

***

### Works Best With

For the best results, use this scraper
alongside [Facebook Posts Search](https://apify.com/scraper_one/facebook-posts-search).

Before extracting comments, you can use the Facebook Posts Search actor to gather post URLs based on specific keywords.
Then, pass those URLs into this Facebook
Comments Scraper to collect comments associated with those posts.
✅ Best Use Case Scenario

- Run Facebook Posts Search Scraper → Collect posts based on your search criteria.
- Feed post URLs into Facebook Comments Scraper → Extract comments for each post.
- Gain complete insights → Combine posts and comments for a full dataset, useful for engagement analysis, sentiment
  tracking, and social media monitoring.

This combination provides a powerful way to analyze conversations happening around specific posts! 🚀

### Other Recommended Scrapers

If you're working with multiple platforms or want additional data sources, check out these scrapers:

- 🐦 [X (Twitter) Posts Search](https://apify.com/scraper_one/x-posts-search) — Find posts/tweets based on keywords, hashtags, and more
- 🐦 [X (Twitter) Post Replies Scraper](https://apify.com/scraper_one/x-post-replies-scraper) — Scrap replies of multiple X (Twitter) posts
- 🐦 [X (Twitter) Profile Posts Scraper](https://apify.com/scraper_one/x-profile-posts-scraper) — Scrap posts by specified X profiles/users
- 📘 [Facebook Posts Search](https://apify.com/scraper_one/facebook-posts-search) — Discover Facebook posts for a given topic or page
- 📘 [Facebook Comments Scraper](https://apify.com/scraper_one/facebook-comments-scraper) — Extract comments from public Facebook posts
- 📘 [Facebook Reactions Scraper](https://apify.com/scraper_one/facebook-reactions-scraper) — Scrap reactions from Facebook posts (like, sad, haha, angry etc.)
- 📘 [Facebook Posts Scraper](https://apify.com/scraper_one/facebook-posts-scraper) — Scrap posts from Facebook pages, groups etc.
- 💬 [YouTube Search Scraper](https://apify.com/scraper_one/youtube-search-scraper) — Extract search results from YouTube
- 💬 [YouTube Comments Scraper](https://apify.com/scraper_one/youtube-comments-scraper) — Extract comments from YouTube videos
- 🎬 [YouTube Downloader](https://apify.com/scraper_one/yt-downloader) — Download youtube videos

### Support & Contact

✉️ If you encounter issues or need help, feel free to **open an issue** or contact us at **scraper1one@gmail.com**.

# Actor input Schema

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

List of Facebook post, group post, photo, reel, video or share URLs to process. Note: Free-plan users can process up to 5 post URLs per run.

## `resultsLimit` (type: `integer`):

Maximum number of results to retrieve per post, including the original post when includeOriginalPost is enabled. If not set, only a few of the first comments will be returned. Note: Free-plan users can retrieve up to 100 results per post URL, including the original post when enabled.

## `commentsSortType` (type: `string`):

Comments sorting - i.e. what kind of comments to scrape for. If not set, the sorting initially selected by Facebook for each post will be used. Note: Choosing 'All comments' still requires setting a 'Results Limit'.

## `includeOriginalPost` (type: `boolean`):

If true, the original post will be included as a first reply.

## Actor input object example

```json
{
  "postUrls": [
    "https://www.facebook.com/NFL/posts/pfbid037dWXDmChUtBRycRAoowDn6oSsv5Qjnr5ZC4tbAYGTtPeJuWGS27JgqsdpjdR1Hwzl",
    "https://www.facebook.com/oldmillartsOMA/posts/pfbid02gEbMLP6JZfCfyjh62nC7VkxYhtzp1heiTTnrAW57qNnZZ7r2Z31Ponn6tfPooRJyl"
  ],
  "resultsLimit": 20,
  "includeOriginalPost": false
}
```

# Actor output Schema

## `results` (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/NFL/posts/pfbid037dWXDmChUtBRycRAoowDn6oSsv5Qjnr5ZC4tbAYGTtPeJuWGS27JgqsdpjdR1Hwzl",
        "https://www.facebook.com/oldmillartsOMA/posts/pfbid02gEbMLP6JZfCfyjh62nC7VkxYhtzp1heiTTnrAW57qNnZZ7r2Z31Ponn6tfPooRJyl"
    ],
    "resultsLimit": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("scraper_one/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/NFL/posts/pfbid037dWXDmChUtBRycRAoowDn6oSsv5Qjnr5ZC4tbAYGTtPeJuWGS27JgqsdpjdR1Hwzl",
        "https://www.facebook.com/oldmillartsOMA/posts/pfbid02gEbMLP6JZfCfyjh62nC7VkxYhtzp1heiTTnrAW57qNnZZ7r2Z31Ponn6tfPooRJyl",
    ],
    "resultsLimit": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("scraper_one/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/NFL/posts/pfbid037dWXDmChUtBRycRAoowDn6oSsv5Qjnr5ZC4tbAYGTtPeJuWGS27JgqsdpjdR1Hwzl",
    "https://www.facebook.com/oldmillartsOMA/posts/pfbid02gEbMLP6JZfCfyjh62nC7VkxYhtzp1heiTTnrAW57qNnZZ7r2Z31Ponn6tfPooRJyl"
  ],
  "resultsLimit": 20
}' |
apify call scraper_one/facebook-comments-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scraper_one/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/ReLdaLwxK0nasygz1/builds/ZDUxSARbcXB4ppZzH/openapi.json
