# Facebook Posts Scraper (`scraper_one/facebook-posts-scraper`) Actor

Scrape Facebook posts from Facebook profiles, pages, groups etc. Retrieve post URLs, content, publication dates, author details, and engagement metrics. Ideal for Facebook monitoring solutions.

- **URL**: https://apify.com/scraper_one/facebook-posts-scraper.md
- **Developed by:** [Scraper One](https://apify.com/scraper_one) (community)
- **Categories:** Automation, Developer tools, Lead generation
- **Features:** Limited permissions
- **Stats:** 2,197 total users, 302 monthly users, 100.0% runs succeeded, 25 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $2.00 / 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 Posts Scraper

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

This apify actor **scrapes public posts from Facebook** groups, pages, or hashtag feeds based on input URLs. It supports **pagination and returns data including post content,
timestamp, number of comments, reactions, and author information**. Ideal for **social media monitoring** solutions.

You can also provide direct URLs of individual public posts, group posts, reels, and videos.
Hashtag feeds such as `https://www.facebook.com/hashtag/respectorders` are supported,
including input URLs that redirect to a hashtag feed.
Hashtag feeds use latest results by default.

Date filters are ignored for hashtag feeds.

### Input

The actor accepts the following input fields:

| Field          | Type       | Required | Description                                                                                                                                                                      |
|----------------|------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `pageUrls`     | `string[]` | ✅        | A list of Facebook group or page URLs to scrape posts from.                                                                                                                      |
| `resultsLimit` | `number`   | ❌        | Maximum number of posts to extract from each URL (default: 10).                                                                                                                  |
| `onlyPostsNewerThan` | `string` | ❌ | Optional first day to include (`YYYY-MM-DD`, UTC). Supported for pages and groups; ignored for hashtag feeds. |
| `onlyPostsOlderThan` | `string` | ❌ | Optional last day to include (`YYYY-MM-DD`, includes the whole day in UTC). Supported for pages; ignored for groups and hashtag feeds. |

#### Example input

```json
{
    "resultsLimit": 3,
    "pageUrls": [
        "https://www.facebook.com/groups/1054903574928547",
        "https://www.facebook.com/tweakedmotorsports",
        "https://www.facebook.com/groups/289835267786139"
    ]
}
```

#### Example input with a date range

```json
{
    "resultsLimit": 20,
    "pageUrls": [
        "https://www.facebook.com/NFL"
    ],
    "onlyPostsNewerThan": "2023-03-01",
    "onlyPostsOlderThan": "2023-03-31"
}
```

#### Example input with page and individual post URLs

You can mix page URLs and direct links to individual posts in the same input:

```jsonc
{
    "resultsLimit": 3,
    "pageUrls": [
        // Page URL — collect posts from this page
        "https://www.facebook.com/knowyourmeme",

        // Direct post URL — collect this individual post
        "https://www.facebook.com/knowyourmeme/posts/1528500792655485",

        // Direct reel URL is also supported
        "https://www.facebook.com/reel/2571258890059094"
    ]
}
```

Remove comments before using this example as JSON input.

`resultsLimit` applies to each input URL. A direct link to an individual post, reel, or video returns at most one result.
Direct links to group posts and videos are also supported, including `/groups/.../permalink/...`, `/watch/?v=...`, and `/.../videos/...`.
Facebook share links that lead to supported content can also be used.
For individual posts, reels, and videos, both date filters apply, including individual group posts; an item outside the selected date range is not returned.

### Output

The actor outputs an array of post objects in JSON format with the following fields. When Facebook provides a tagged
location for a post, its ID is returned in the optional `taggedLocationId` field.
The optional `sharesCount` field contains the number of shares when Facebook provides an exact numeric count.
It is omitted when the share count is unavailable.

`inputUrl` identifies the original input URL for pages, groups, individual posts, reels, and videos, while `url` is the content URL returned by Facebook.
These addresses can differ, for example when a share link leads to a post or a `watch` link returns a `reel` URL.

**Deprecated:** `pageUrl` contains the normalized input URL and is retained for backward compatibility. Use `inputUrl` instead.

#### Example output

```json
{
    "url": "https://www.facebook.com/groups/1054903574928547/permalink/2303563860062506/",
    "pageUrl": "https://www.facebook.com/groups/1054903574928547",
    "inputUrl": "https://www.facebook.com/groups/1054903574928547",
    "timestamp": 1752519380000,
    "postText": "Hey, how can I save my geranium? I repotted it and now it’s wilting before my eyes. 😔",
    "reactionsCount": 3,
    "reactions": {
        "like": 3,
        "love": 10,
        "sad": 15,
        "angry": 4,
        "haha": 1
    },
    "commentsCount": 20,
    "sharesCount": 2,
    "isReshare": false,
    "sharedPost": null,
    "postId": "2303563860062506",
    "taggedLocationId": "109524955741121",
    "author": {
        "id": "100055230212550",
        "name": "Yyyyy Tttttt",
        "profilePicture": "https://scontent-mad2-1.xx.fbcdn.net/v/t39.30808-1/274300141_461291382388532_2921259538884887660_n.jpg?...",
        "profileUrl": "https://www.facebook.com/kttata.adasda.44"
    },
    "attachments": [
        {
            "type": "photo",
            "url": "https://scontent.fpoz3-1.fna.fbcdn.net/v/t39.30808-6/805805802_10167424495778942_2119050250610320982_n.jpg?stp=dst-jpg_tt6&cstp=mx2048x1536&ctp=s2048x1536&_nc_cat=109&ccb=1-7&_nc_sid=aa7b47&_nc_ohc=nDfW8CwH7eYQ7kNvwGTDcr3&_nc_oc=AdqjS9IUfkGRBUydeYh0oNo_Q_ncMOnLqoyBPYlyNFxhzYh4DRNw7_W9MIlNbNnQA-o&_nc_zt=23&_nc_ht=scontent.fpoz3-1.fna&_nc_gid=vLuoo5GCOAZwj57ayS-O7w&_nc_ss=7b2a8&oh=00_AQLqOsIqm2inOBfatn2_dQqun2saltWbuegBX0pXVB9axQ&oe=6AAB5415",
            "id": "10162424501293942",
            "accessibilityCaption": "May be an image of speaker, lighting and text"
        }
    ]
}
```

#### Example output for a shared post

```json
{
    "url": "https://www.facebook.com/auroraaudio/posts/pfbid02R48dV6WxBU59mfg8nDBPLY3rZBdGqJ6QSThgA9MTzSooLxibptb54BhuS3DhhyRm",
    "pageUrl": "https://www.facebook.com/NorthHiFi",
    "inputUrl": "https://www.facebook.com/NorthHiFi",
    "timestamp": 1749803809000,
    "postText": "",
    "reactionsCount": 417,
    "reactions": {
        "like": 371,
        "love": 42,
        "support": 3,
        "wow": 1
    },
    "commentsCount": 31,
    "sharesCount": 19,
    "isReshare": true,
    "sharedPost": {
        "postId": "716284953810627",
        "url": "https://www.facebook.com/auroraaudio/posts/pfbid02R48dV6WxBU59mfg8nDBPLY3rZBdGqJ6QSThgA9MTzSooLxibptb54BhuS3DhhyRm",
        "postText": "A new review of our AA6-MKII integrated amplifier is out! Thank you for the kind words and the listening session.",
        "author": {
            "id": "100080039527614",
            "name": "AURORA AUDIO",
            "profilePicture": "https://scontent.fpoz3-1.fna.fbcdn.net/v/t39.30808-1/328395162_896374205618293_2694187352069871435_n.jpg?...",
            "profileUrl": "https://www.facebook.com/auroraaudio"
        },
        "timestamp": 1749803809000,
        "attachments": [
            {
                "type": "photo",
                "url": "https://scontent.fpoz3-1.fna.fbcdn.net/v/t39.30808-6/505793216_716291997143256_2113985267041829653_n.jpg?...",
                "id": "716291987143257",
                "accessibilityCaption": "May be an image of an amplifier and review text"
            }
        ]
    },
    "postId": "1222096845078316",
    "author": {
        "id": "100057092683415",
        "name": "NorthHiFi",
        "profilePicture": "https://scontent.fpoz3-1.fna.fbcdn.net/v/t39.30808-1/309874652_589306247815923_5332871964085637214_n.jpg?...",
        "profileUrl": "https://www.facebook.com/northhifi"
    }
}
```

###### Let me know if you need additional output fields! 🤙

#### URL errors

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

- `INVALID_URL`: invalid or unsupported URL.
- `PAGE_UNAVAILABLE`: content confirmed unavailable.
- `PRIVATE_GROUP`: a private group whose feed could not be accessed.

An empty group alone does not produce this error.

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

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

Two posts from one input URL and an error for another (selected fields shown):

```json
[
    {
        "inputUrl": "https://www.facebook.com/example-page",
        "url": "https://www.facebook.com/example-page/posts/123",
        "postId": "123",
        "postText": "First example post."
    },
    {
        "inputUrl": "https://www.facebook.com/example-page",
        "url": "https://www.facebook.com/example-page/posts/456",
        "postId": "456",
        "postText": "Second example post."
    },
    {
        "inputUrl": "https://www.facebook.com/unavailable-page",
        "error": "PAGE_UNAVAILABLE"
    }
]
```

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

- 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 page URLs per run** and retrieve up to **100 posts per page URL**.
- Free users are rate-limited to a certain number of processed page 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 Comments Scraper](https://apify.com/scraper_one/facebook-comments-scraper).

Before extracting comments, you can use the Facebook Posts Scraper actor to gather post URLs from specified pages. Then, pass those URLs into Facebook
Comments Scraper to collect comments associated with those posts.
✅ Best Use Case Scenario

- Run Facebook Posts Scraper → Collect posts from facebook pages.
- 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 of specific X (Twitter) profile
- 📘 [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 videos from search queries
- 🎬 [YouTube Comments Scraper](https://apify.com/scraper_one/youtube-comments-scraper) — Extract comments from posted 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

## `pageUrls` (type: `array`):

List of Facebook page, group, hashtag, or individual post URLs to process. Note: Free-plan users can process up to 5 page URLs per run.

## `onlyPostsNewerThan` (type: `string`):

Get posts starting from given date (YYYY-MM-DD, inclusive, UTC). Ignored for hashtag feeds.

## `onlyPostsOlderThan` (type: `string`):

Get posts ending on given date (YYYY-MM-DD, includes the whole day in UTC). Ignored for groups and hashtag feeds.

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

Maximum number of posts to retrieve per page. If not set, only a few of the first posts will be returned. Note: Free-plan users can retrieve up to 100 posts per page URL.

## Actor input object example

```json
{
  "pageUrls": [
    "https://www.facebook.com/NFL",
    "https://www.facebook.com/oldmillartsOMA"
  ],
  "resultsLimit": 10
}
```

# 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 = {
    "pageUrls": [
        "https://www.facebook.com/NFL",
        "https://www.facebook.com/oldmillartsOMA"
    ],
    "resultsLimit": 10
};

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

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

```

## MCP server setup

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