# Facebook Posts & Pages Scraper (`rexreus/facebook-posts-pages-scraper`) Actor

Public Facebook page metadata and posts in one run. HTTP-first, tokenless by default, optional Graph API token mode for comments and deep pagination.

- **URL**: https://apify.com/rexreus/facebook-posts-pages-scraper.md
- **Developed by:** [REXREUS D.O](https://apify.com/rexreus) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 results

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?

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 & Pages Scraper

![Facebook Posts & Pages Scraper banner](https://res.cloudinary.com/ewnqk3k9/image/upload/f_auto,q_auto/v1791663957/apify-actors/banners/facebook-posts-pages-scraper-banner.png)

> Public Facebook page metadata and posts in one run. HTTP-first, **tokenless by default**, optional Graph API token mode for comments and deep pagination.

**Features**

- 🏢 **Page info** — name, followers, likes, category, about, website, verified flag
- 📝 **Recent posts** — text, timestamp, reactions, comment count, shares, media
- 🔓 **Tokenless mode** — no login, no access token, pure HTTP requests
- 🔑 **Graph token mode (optional)** — per-emoji reaction breakdown, comments, deep pagination
- 📇 **Contact extraction** — email, phone, website, address from page/about (always on) and post text (opt-in)
- ⚡ **Cheap** — HTTP-only (no headless browser): ~0.01–0.05 CU per page
- 🔄 **Incremental mode** — skip posts already scraped, only emit new ones

***

### What it does

Give it Facebook page URLs (or bare usernames like `NASA`). For each URL the Actor:

1. Fetches the public page over HTTP (no browser, no login) and emits a **page item**: name, followers, likes, category, about, and publicly listed contact details.
2. Collects **~1–6 recent posts per URL** from the page HTML, then optionally fetches permalinks to extend coverage up to `maxPosts` per page. Each post is emitted with text, timestamp, engagement counts, and media URLs.
3. Optionally regex-extracts **emails and phone numbers** from post text (off by default for PII minimization).

Optionally, provide a **Graph API access token** to unlock comments per post, per-emoji reaction breakdowns, and deep pagination beyond what the HTML yields.

***

### Tokenless vs Graph token mode

| Capability | Tokenless (default) | Graph token |
|---|---|---|
| Page info & about | ✅ | ✅ |
| Recent posts (~1–6 per URL) | ✅ | ✅ |
| Extended posts via permalinks (up to `maxPosts`) | ✅ | ✅ |
| Post reactions total | ✅ | ✅ |
| Per-emoji reaction breakdown | ❌ | ✅ |
| Comments + comment counts | ❌ | ✅ (capped by `maxCommentsPerPost`) |
| Deep pagination | ❌ | ✅ |
| Setup | None | Facebook Graph API access token |
| Cost per page | ~0.01–0.05 CU | Slightly higher (per-comment fetching) |

***

### Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array *(required)* | — | Facebook page URLs or usernames (e.g. `https://www.facebook.com/NASA` or `NASA`). Max 100. |
| `maxPosts` | integer | `20` | Max posts per page (1–500). Tokenless: HTML yields ~4–6; permalink fetches extend up to this cap. |
| `since` | string | — | ISO 8601 date. Posts older than this are skipped. |
| `until` | string | — | ISO 8601 date. Posts newer than this are skipped. |
| `keyword` | string | — | Only keep posts whose text contains this keyword (case-insensitive). Max 200 chars. |
| `includePageInfo` | boolean | `true` | Emit a page dataset item per start URL. |
| `extractContactsFromPosts` | boolean | `false` | Regex-extract emails/phones from post **text** (not comments). Page/about contact extraction is always on. Off by default for PII minimization. |
| `incremental` | boolean | `false` | Skip posts already emitted by a previous run (key-value store state). Only new posts are pushed. |
| `graphAccessToken` | string *(secret)* | — | Optional Graph API token. Unlocks comments, reaction breakdown, deep pagination. Leave empty for tokenless HTTP mode. |
| `maxCommentsPerPost` | integer | `50` | Cap on comments fetched per post in Graph mode (1–200). Prevents runaway cost on viral posts. |
| `proxyConfiguration` | object | — | Residential proxy recommended for Apify datacenter IPs. Facebook blocks datacenter ASNs aggressively. |

**Example input**

```json
{
  "startUrls": ["https://www.facebook.com/NASA", "nike"],
  "maxPosts": 30,
  "keyword": "launch",
  "includePageInfo": true,
  "extractContactsFromPosts": false,
  "incremental": true
}
```

***

### Output

Each dataset item carries a `type` field (`page` or `post`) plus a `status` / `httpStatus` result indicator.

#### Page item

```json
{
  "type": "page",
  "status": "SUCCESS",
  "httpStatus": 200,
  "pageId": "1234567890",
  "pageUrl": "https://www.facebook.com/NASA",
  "name": "NASA",
  "followers": 75400000,
  "likes": 73000000,
  "category": "Government organization",
  "about": "Explore the universe and discover our home planet with NASA.",
  "email": "public-inquiries@nasa.gov",
  "phone": "+1 202-358-0001",
  "website": "https://www.nasa.gov",
  "address": "300 E St SW, Washington, DC 20546",
  "messenger": "https://m.me/NASA",
  "verified": true
}
```

#### Post item (tokenless)

```json
{
  "type": "post",
  "status": "SUCCESS",
  "httpStatus": 200,
  "pageId": "1234567890",
  "postId": "1234567890_10159876543210000",
  "url": "https://www.facebook.com/NASA/posts/10159876543210000",
  "text": "Our newest mission is a go! Read more about what's next for exploration…",
  "timestamp": "2026-10-08T14:32:00.000Z",
  "reactionsTotal": 48210,
  "reactions": {},
  "commentsCount": 512,
  "comments": {},
  "shares": 3105,
  "media": ["https://scontent.xx.fbcdn.net/.../photo.jpg"],
  "extractedContacts": {}
}
```

**Field notes**

- `reactions` (per-emoji breakdown) and `comments` (comment objects) are only populated in **Graph token mode**; they stay empty `{}` in tokenless mode.
- `extractedContacts` applies to post items only: extracted from post text when `extractContactsFromPosts=true` (default `false`). Page/about contact fields (`email`, `phone`, `address`, `messenger`) come from the page's own published info.
- `httpStatus` reflects the last HTTP response for the item; `status` is one of `SUCCESS`, `PARTIAL`, `NOT_FOUND`, `BLOCKED`, `ERROR`.

***

### Use cases

- **Brand monitoring** — track followers, engagement, and recent posts on your own and partner pages; keyword-filter for mentions.
- **Competitor analysis** — compare categories, follower counts, posting cadence, and top-performing posts across rival pages.
- **Market research** — profile public pages in a niche (categories, contact info, audience size) in bulk.
- **Lead extraction** — harvest publicly listed emails, phones, and websites from business pages; opt into post-text contact extraction when relevant.

***

### FAQ

**Do I need to log in?**
No. Tokenless mode never logs in and never handles cookies. All data comes from publicly served page HTML. A Graph API token is optional and unlocks extra fields — you obtain it from Facebook yourself; the Actor never stores it.

**What are the tokenless limits?**
Tokenless HTML yields roughly **1–6 recent posts per URL** (typically ~4–6), extendable toward `maxPosts` via permalink fetches. No comments, no per-emoji reaction breakdown, no deep pagination in this mode.

**Does incremental mode work?**
Yes — set `incremental: true` and the Actor records emitted post IDs in its key-value store. Subsequent runs push only new posts.

**How does contact extraction work?**
Emails/phones/websites/addresses found on the page and its about information are always extracted. Post text is only scanned when `extractContactsFromPosts` is enabled (default `false`, for PII minimization).

**Do I need a proxy?**
Strongly recommended. Facebook blocks datacenter IP ranges aggressively. Configure `proxyConfiguration` (residential recommended) for reliable runs — Apify's default residential proxy works out of the box.

***

### Cost & performance

- **HTTP-first** — every request is plain HTTP via `got-scraping` with browser-like headers. No headless browser, no CDP, no page rendering.
- **Cost**: ~**0.01–0.05 CU per page** in tokenless mode (page fetch + up to `maxPosts` cheap permalink fetches).
- **Runtime**: tens of seconds for a handful of pages; scales linearly with URLs and `maxPosts`.
- To keep costs down: reduce `maxPosts`, use `since`/`until` windows, and enable `incremental` for repeated monitoring runs.

***

### Personal data & lawful basis

> \[!IMPORTANT]
> This Actor extracts **publicly available** Facebook data, which may include **personal data** (names of page admins implied by page names, contact details listed on pages, usernames in post text).

- **PII disclosure**: Page-level contact fields (`email`, `phone`, `address`, `messenger`) are published by page owners voluntarily. `extractedContacts` from post text may contain personal contact details of commenters/authors — that is why it is **off by default**.
- **Buyer responsibility**: You, the buyer, are the data controller for whatever you scrape. Under GDPR and similar laws you need a **lawful basis** (e.g. legitimate interest assessment) before processing personal data. Do not scrape private profiles, do not build contact lists for spam, and honor data-subject rights (deletion requests) for data you store.
- This Actor only accesses content Facebook serves without authentication. If you cannot articulate a lawful basis for your use case, do not run it.

***

### Limitations

- Tokenless mode cannot read posts older than what the public page serves.
- Private pages, groups, and login-gated content are never accessed.
- Facebook markup changes can intermittently affect extraction — the `status`/`httpStatus` fields on each item let you monitor success rates.

***

### License

**LICENSED** — all rights reserved. © 2026 REXREUS

# Actor input Schema

## `startUrls` (type: `array`):

Facebook page URLs or usernames to scrape (e.g. https://www.facebook.com/NASA or NASA). Max 100.

## `maxPosts` (type: `integer`):

Maximum posts to extract per page. Tokenless mode: page HTML yields ~4-6 posts; permalink fetches extend up to this cap.

## `since` (type: `string`):

ISO 8601 date. Posts older than this are skipped.

## `until` (type: `string`):

ISO 8601 date. Posts newer than this are skipped.

## `keyword` (type: `string`):

Only keep posts whose text contains this keyword (case-insensitive). Max 200 chars.

## `includePageInfo` (type: `boolean`):

Emit a page dataset item (name, followers, category, about, contact) per start URL.

## `extractContactsFromPosts` (type: `boolean`):

Regex-extract emails/phones from post TEXT (not comments). Page/about contact extraction is always on. Off by default for PII minimization.

## `incremental` (type: `boolean`):

Skip posts already emitted by a previous run (key-value store state). Only new posts are pushed.

## `graphAccessToken` (type: `string`):

Optional Facebook Graph API token. Unlocks: comments per post, deep pagination, per-emoji reaction breakdown. Leave empty for tokenless HTTP mode.

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

Cap on comments fetched per post in Graph token mode. Prevents runaway cost on viral posts.

## `proxyConfiguration` (type: `object`):

Residential proxy recommended for Apify datacenter IPs. Facebook blocks datacenter ASNs aggressively.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.facebook.com/NASA"
    }
  ],
  "maxPosts": 20,
  "includePageInfo": true,
  "extractContactsFromPosts": false,
  "incremental": false,
  "maxCommentsPerPost": 50
}
```

# Actor output Schema

## `defaultDatasetUrl` (type: `string`):

URL to the run's default dataset items.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.facebook.com/NASA"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("rexreus/facebook-posts-pages-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 = { "startUrls": [{ "url": "https://www.facebook.com/NASA" }] }

# Run the Actor and wait for it to finish
run = client.actor("rexreus/facebook-posts-pages-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 '{
  "startUrls": [
    {
      "url": "https://www.facebook.com/NASA"
    }
  ]
}' |
apify call rexreus/facebook-posts-pages-scraper --silent --output-dataset

```

## MCP server setup

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