# Facebook Group Posts & Comments Scraper (`swerve/fb-group-scraper`) Actor

Scrape public Facebook group posts and, optionally, the people who COMMENT on them (repliers), with no login. Get post text, author, time, images, reactions, plus each commenter's name, profile link, text, and any phone number. Great for lead generation. Turn on Fetch comments to include repliers.

- **URL**: https://apify.com/swerve/fb-group-scraper.md
- **Developed by:** [Swerve](https://apify.com/swerve) (community)
- **Categories:** Social media, Lead generation
- **Features:** Limited permissions
- **Stats:** 449 total users, 53 monthly users, 96.0% runs succeeded, 3 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Group Posts & Comments Scraper

Extract posts from **public Facebook groups** - no login, no cookies, no API token needed. Just provide group URLs and get structured post data. Optionally, also capture the people who **comment** on each post (repliers) - names, profiles, text, and phone numbers - which is ideal for lead generation.

### What makes this scraper different?

| Feature | This Scraper | Other Scrapers |
|---|---|---|
| **Comments (repliers)** | Optional: commenter name, profile, text, phone | Count only, or none |
| **Images** | All images per post (avg 4) | First image only or none |
| **Posts per group** | Up to 50 (cursor pagination) | 3-5 per group |
| **Speed** | Parallel scraping (3 groups at once) | Sequential |
| **Login required** | No | No |

Turn on **Fetch comments** to include repliers. To keep it cheap, the scraper reads the comment count from the feed and only opens the posts that actually have comments (posts with zero comments are skipped).
| **Private groups** | Optional (with cookies) | Not supported |

### Use Cases

- **Real estate companies** harvesting apartment-for-rent posts from local FB housing groups to build listing feeds competitors don't have
- **Market researchers** tracking brand mentions, sentiment, and trending topics across niche hobbyist and industry communities
- **Recruiting teams** monitoring jobs-wanted and jobs-offered groups to source passive candidates in tech, design, and trades
- **E-commerce sellers** scanning buy/sell/swap groups for product demand signals, price benchmarks, and resale opportunities
- **Journalists and OSINT analysts** archiving public posts with full image sets for reporting, fact-checking, and event reconstruction
- **Community managers** benchmarking engagement (likes, comments, shares) on competing groups to sharpen their own content strategy

### What data can you extract?

| Field | Description |
|---|---|
| `text` | Full post text content |
| `url` | Direct permalink to the post |
| `time` | ISO 8601 timestamp |
| `user` | Author info: `{ id, name }` |
| `imageUrl` | First image URL (convenience) |
| `images` | All image URLs from the post |
| `likesCount` | Total reactions (likes, love, etc.) |
| `commentsCount` | Number of comments |
| `sharesCount` | Number of shares |
| `comments` | Repliers on the post (only when **Fetch comments** is on) |
| `facebookUrl` | Source group URL |
| `groupTitle` | Group name |

#### Comments (repliers)

Turn on **Fetch comments** to also capture the people replying to each post — useful for finding buyers/renters who comment on listings (rent *and* sale). No login required. Each post gains a `comments` array:

```json
"comments": [
  { "id": "10164677056970943", "authorName": "Dana L.", "authorId": "712056041",
    "authorUrl": "https://www.facebook.com/712056041",
    "text": "Interested! is it still available? 052-7902388", "phone": "0527902388",
    "time": "2026-06-30T12:34:00.000Z", "depth": 0 }
]
```

`depth` is 0 for a top-level comment, higher for replies. `phone` is any Israeli number found in the comment text. It costs one extra request per post (slower). Note: it captures the comments shown on the post page (the most recent/visible set), not deep pagination of very large threads.

### How to use

1. Create a free Apify account
2. Open this scraper
3. Add one or more public Facebook group URLs
4. Set how many posts you want per group (default: 10)
5. Click **Start** and wait for results
6. Download in JSON, CSV, Excel, or HTML

### Input example

```json
{
  "startUrls": [
    { "url": "https://www.facebook.com/groups/webscrapingandautomation" },
    { "url": "https://www.facebook.com/groups/selftaughtprogrammers" }
  ],
  "maxPostsPerGroup": 10,
  "resultsLimit": 100
}
```

### Output example

```json
{
  "text": "Looking for a 2-bedroom apartment in downtown...",
  "url": "https://www.facebook.com/groups/123456/posts/789012/",
  "time": "2026-04-19T13:24:48.000Z",
  "facebookUrl": "https://www.facebook.com/groups/123456",
  "groupTitle": "Apartments for Rent",
  "user": {
    "id": "1751460557",
    "name": "John Smith"
  },
  "imageUrl": "https://scontent.xx.fbcdn.net/v/t39.30808-6/photo1.jpg",
  "images": [
    "https://scontent.xx.fbcdn.net/v/t39.30808-6/photo1.jpg",
    "https://scontent.xx.fbcdn.net/v/t39.30808-6/photo2.jpg",
    "https://scontent.xx.fbcdn.net/v/t39.30808-6/photo3.jpg"
  ],
  "likesCount": 5,
  "commentsCount": 12,
  "sharesCount": 2
}
```

### Input options

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | required | List of Facebook group URLs to scrape |
| `maxPostsPerGroup` | number | 10 | Max posts to extract per group (uses pagination) |
| `resultsLimit` | number | 100 | Total max posts across all groups |
| `cookies` | string | empty | Optional Facebook cookies for private group access |
| `proxyCountry` | string | US | Proxy country code (use group's country for best results) |

### How it works

This scraper uses Facebook's internal GraphQL API to extract structured post data. It:

1. Fetches the public group page to obtain CSRF tokens (no login needed)
2. Calls Facebook's GraphQL endpoint with cursor pagination
3. Parses the structured response to extract post data, images, and engagement metrics
4. Processes multiple groups in parallel for speed

All requests go through Apify residential proxies - no risk of IP blocking.

### Private / closed groups

Public groups work straight out of the box, no cookies needed.

For **private or closed groups**, the scraper needs to act as a logged-in Facebook user who is already a member of that group. There is no way around this: Facebook only exposes private-group posts to members, and we cannot join groups on your behalf.

To scrape a private group, paste your Facebook session cookies into the `cookies` field. The account those cookies belong to **must already be a member of the group** before you run the scraper.

#### How to copy your Facebook cookies

**Easiest — via a browser extension:**

1. Install a cookie-export extension. Two popular ones:
   - [Cookie-Editor](https://chromewebstore.google.com/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm) (Chrome / Edge / Brave / Firefox)
   - EditThisCookie
2. Log in to facebook.com with the account that is a member of the group.
3. Click the extension icon while you're on facebook.com.
4. Choose **Export → Header String** (or "Copy as HTTP header" depending on the extension).
5. Paste the result into the `cookies` field of this actor.

Both export formats work: if your extension only offers **Export as JSON**, paste that JSON output directly into the `cookies` field and the actor will convert it automatically.

**Manual — via your browser's developer tools:**

1. Open facebook.com and log in with the account that is a member of the group.
2. Press `F12` (or right-click anywhere on the page → **Inspect**).
3. Open the **Application** tab (Chrome / Edge / Brave) or the **Storage** tab (Firefox).
4. In the left sidebar, expand **Cookies** and click on `https://www.facebook.com`.
5. Find these rows and copy each one's `Value`: **c\_user**, **xs**, **datr**, **fr**, **sb**.
6. Paste them into the `cookies` field as one line separated by `; `, like:
   ```
   c_user=12345; xs=abcd; datr=efgh; fr=ijkl; sb=mnop
   ```

#### What if I get 0 posts?

If the run completes successfully but returns zero posts, the log will tell you why. The most common causes:

- **"cookies were accepted but the account is NOT a member"** → the Facebook account those cookies came from needs to JOIN the group first.
- **"cookies expired or invalid"** → log out and back in to Facebook, then re-copy the cookies.
- **No error, just an empty feed** → the group is accessible but has no recent posts in the chronological feed.

#### Security note

These cookies grant full access to your Facebook account. Apify encrypts the `cookies` field at rest, but you should still treat it like a password. Don't share runs that contain these cookies, and rotate the session (log out + log in) if you're worried.

### Pricing

This scraper uses Apify's pay-per-result pricing. You only pay for the posts you extract - no wasted compute on empty pages or failed requests.

### FAQ

**Q: Do I need a Facebook account?**
No. This scraper works without login for public groups.

**Q: How many posts can I get per group?**
Up to 50 per group using cursor pagination. Default is 10.

**Q: Can I scrape private groups?**
Yes, but the Facebook account whose cookies you paste must already be a member of the group. Facebook only shows private-group posts to members, so we cannot scrape a private group on your behalf without member-level access. See the "Private / closed groups" section above for how to copy your cookies.

**Q: Will my IP get blocked?**
No. All requests go through Apify's residential proxy network, which rotates IPs automatically.

**Q: What languages are supported?**
All languages. The scraper extracts raw text content regardless of language.

### Integrations

Export data via API, webhooks, or integrate with:

- Google Sheets, Slack, Zapier, Make
- Python & Node.js SDKs
- Any app via Apify API

### Keywords

Facebook group scraper, Facebook posts API, FB group data extractor, Facebook public groups scraper, social media monitoring, Facebook group posts, scrape Facebook without login, FB group content export, Facebook OSINT tool, social listening Facebook, Facebook group analytics, Facebook community data

# Actor input Schema

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

One or more Facebook group URLs (e.g. https://www.facebook.com/groups/123456789 or https://www.facebook.com/groups/some-slug — both work). For private/closed groups you must also paste cookies below, from an account that is a member of the group.

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

Optional cost cap on the total number of posts returned across every group combined. Leave this blank to return ALL matching posts from every group. If you set a number, the actor stops once it reaches that total. There is no upper limit, so on large groups a blank value can return a lot of posts (you pay per result). Example: set 500 to stop after 500 posts total.

## `maxPostsPerGroup` (type: `integer`):

Optional cost cap on how many posts to take from each single group. Leave this blank to scrape ALL available posts from every group. If you set a number, scraping of a group stops after that many posts. Combined with the total limit above, whichever is hit first wins. Big or active groups can hold thousands of posts, so a blank value can return a lot (you pay per result). Example: set 25 to take at most 25 posts per group.

## `postedAfter` (type: `string`):

Optional. Only return posts published on or after this date. Accepts ISO format (YYYY-MM-DD). Useful for monitoring a group over time without re-scraping old posts.

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

Optional. Only return posts whose text contains this string (case-insensitive). Useful for lead-gen, brand monitoring, or moderation use cases.

## `fetchComments` (type: `boolean`):

OFF by default. Turn ON to also collect the people who COMMENT on each post, not just the post. Each post gets a 'comments' list: the commenter's name, profile link, comment text, any phone number in the text, timestamp, and reply depth. Perfect for lead generation, e.g. buyers/renters or interested customers replying to a listing. Cost note: this loads each post's page to read its comments, so it uses a bit more time and compute; to keep it cheap we automatically SKIP posts that have zero comments and only fetch the ones that actually have replies. No login needed.

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

Optional cap on how many comments to keep per post. Leave blank to keep all comments available on the post's page. Only applies when 'Fetch comments' is on. Example: 30.

## `knownPostIds` (type: `array`):

Posts you already ingested on a previous run (numeric post ids, or full post URLs - the numeric id is extracted either way). Known posts are still returned from the cheap group-feed fetch, but their page is NOT re-opened to read comments, which is the per-post cost driver. Use this when scanning the same groups on a schedule so you only pay comment fetches for posts you have never seen. Leave empty to fetch comments for every post. Example: \["2174749456705215"].

## `cookies` (type: `string`):

ONLY needed for private or closed groups. Leave EMPTY for public groups.

The Facebook account you copy cookies from MUST already be a member of the target group — we cannot join groups on your behalf.

How to get them (Chrome/Edge/Brave):

1. Open facebook.com in your browser and log in to the account that is a member of the group.
2. Open the browser's developer tools: press F12 (or right-click anywhere → Inspect).
3. Go to the 'Application' tab (Chrome/Edge) or 'Storage' tab (Firefox).
4. In the left sidebar, expand 'Cookies' and click 'https://www.facebook.com'.
5. Find the rows named: c_user, xs, datr, fr, sb. Copy each row's 'Value'.
6. Paste them here as one line, separated by '; ', like: c_user=12345; xs=abcd; datr=efgh; fr=ijkl; sb=mnop

Easier option: install a cookie-export browser extension (e.g. 'Cookie-Editor' or 'EditThisCookie'), open facebook.com, click the extension, choose 'Export as Header String', paste here. JSON exports from cookie extensions (e.g. 'Export as JSON' in Cookie-Editor) are also accepted.

These cookies give full access to your Facebook account. Treat them like a password. Apify stores this field as a secret.

## `repairPostUrls` (type: `array`):

Post permalinks whose photos you lost (Facebook photo links expire after a few days) and want re-read directly from each post's own page. Use this when a post is too old to still appear in the group feed, which is the normal case: a group feed only returns recent posts. When set, the actor does ONLY this and returns { url, images, repair: true } rows; startUrls is not needed. Example: \["https://www.facebook.com/groups/ApartmentsTelAviv/posts/10163389345322194/"].

## Actor input object example

```json
{
  "startUrls": [
    "https://www.facebook.com/groups/digitalmarketing",
    "https://www.facebook.com/groups/secrettelaviv"
  ],
  "resultsLimit": 50,
  "fetchComments": false,
  "repairPostUrls": []
}
```

# 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": [
        "https://www.facebook.com/groups/digitalmarketing",
        "https://www.facebook.com/groups/secrettelaviv"
    ],
    "resultsLimit": 50,
    "repairPostUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("swerve/fb-group-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": [
        "https://www.facebook.com/groups/digitalmarketing",
        "https://www.facebook.com/groups/secrettelaviv",
    ],
    "resultsLimit": 50,
    "repairPostUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("swerve/fb-group-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": [
    "https://www.facebook.com/groups/digitalmarketing",
    "https://www.facebook.com/groups/secrettelaviv"
  ],
  "resultsLimit": 50,
  "repairPostUrls": []
}' |
apify call swerve/fb-group-scraper --silent --output-dataset

```

## MCP server setup

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