Facebook Group Posts & Details Scraper : Comment & Engagement avatar

Facebook Group Posts & Details Scraper : Comment & Engagement

Pricing

$19.99/month + usage

Go to Apify Store
Facebook Group Posts & Details Scraper : Comment & Engagement

Facebook Group Posts & Details Scraper : Comment & Engagement

Scrape Facebook Group posts and full post details at scale. Collect text, images, timestamps, reactions, comments, authors, and engagement metrics. Ideal for community research, sentiment analysis, lead generation, and trend tracking. Export structured data in JSON, CSV, or Excel.

Pricing

$19.99/month + usage

Rating

0.0

(0)

Developer

Scraper Engine

Scraper Engine

Maintained by Community

Actor stats

2

Bookmarked

9

Total users

0

Monthly active users

4 days ago

Last modified

Share

Facebook Group Posts Scraper — Comments, Replies and Analytics

Facebook Group Posts Scraper extracts public Facebook group posts, group profile details, threaded comments and replies, and locally-computed engagement analytics — all returned as clean, structured JSON. Each run captures post text, author, timestamp and permalink alongside group name, privacy and member count, then goes one level deeper into comment threads and per-group posting activity. No login, cookies, or Facebook API key required. Add a group URL below and start a run to see it in action.

❓ What is Facebook Group Posts Scraper?

Facebook Group Posts Scraper is an Apify Actor that pulls posts, group profile details, comments, and reply threads from public Facebook groups, then adds a locally computed engagement-analytics summary per group. It reads directly from Facebook's public, logged-out group and post pages — no Facebook account, login, or API token is needed. It outputs typed JSON rows, built for developers, market researchers, and community managers who need structured Facebook group data without manually clicking through group feeds.

🔓 What Facebook group data is publicly available to scrape?

Anyone can view a public Facebook group's posts, comments, and basic profile details without logging in — that public surface is exactly what Facebook Group Posts Scraper reads.

Data CategoryPublicly available (no login)Gated behind group membership / login
Group name, description, cover photoYes
Rounded member count (e.g. "6.0M members")Yes, rounded onlyExact member count — never exposed to anonymous viewers
Group founding/creation dateNot exposed on the anonymous group page
Posts in a public group — text, author, permalinkYesPosts inside private/closed groups
Comments and nested replies on a public postYes — what Facebook server-renders to an anonymous viewerFull comment history beyond what's rendered/paginated
Member list / individual member profilesNoYes — group membership
Group chat / direct messagesNoNever publicly accessible

Facebook Group Posts Scraper only returns publicly visible data — what any logged-out visitor sees. Nothing behind a login wall.

📚 What data can I extract with Facebook Group Posts Scraper?

Facebook Group Posts Scraper writes four kinds of rows into one dataset — group posts, group profile fields (piggybacked on each post row), threaded comments/replies, and a per-group engagement-analytics summary — each tagged with a type field so they're easy to filter.

📝 Post and group profile fields

Field NameDescription
idFacebook's internal post ID, used to build the permalink and as the parentId for that post's comments
typeRow type — "post" for a group post row
isChildfalse for a post row (only true for comment/reply rows)
parentIdnull for a post row
postTextThe post's own text/body
postAuthorDisplay name of the post's author
postAuthorIdFacebook's internal profile ID for the author (numeric, or a privacy-preserving pfbid… ID)
postAuthorUrlBest-effort profile URL, built from postAuthorId or the author's short name
firstName / lastNameBest-effort split of the author's display/short name
imageFirst image URL found on the post (typically the author's profile picture or an attached photo)
postUrlFull permalink to the post
publishedAtISO-8601 UTC timestamp the post was published
groupUrlCanonical URL of the source group
groupNameGroup's display name
groupVanityGroup's vanity URL/address, if any
groupPrivacyThe privacy label shown on the group page (e.g. "Public group")
groupMemberCountTextRounded member-count string exactly as Facebook shows it
groupMemberCountApproxBest-effort integer parsed from groupMemberCountText
groupDescriptionGroup's public description
groupCreatedAtISO-8601 date the group was founded, when Facebook exposes it — null otherwise, never guessed
groupCoverPhotoUrlURL of the group's cover photo
scrapedAtISO-8601 UTC timestamp the row was scraped

💬 Comment and reply fields

Field NameDescription
idFacebook's internal comment/reply ID
type"comment" for a top-level comment, "reply" for a nested reply
isChildAlways true for comment/reply rows
parentIdThe post ID for a top-level comment, or the parent comment's ID for a reply
postIdID of the post the comment belongs to
postUrlPermalink of the parent post
groupUrlCanonical URL of the source group
threadingDepthNesting depth (0 = top-level comment, 1+ = nested reply)
feedbackIdFacebook's internal feedback-object ID for the comment
dateISO-8601 UTC timestamp the comment/reply was posted
textComment or reply body text
profilePictureURL of the commenter's profile picture
profileIdFacebook's internal profile ID for the commenter
profileNameCommenter's display name
profileUrlCommenter's profile URL, when Facebook exposes one
likesCountNumber of reactions on the comment/reply
repliesCountNumber of replies Facebook reports for that comment
facebookIdLegacy numeric Facebook ID for the comment, when present
scrapedAtISO-8601 UTC timestamp the row was scraped

📈 Engagement analytics fields (one summary row per group)

Field NameDescription
idStable hash-based ID for the group's analytics row
typeAlways "analytics"
groupUrl / groupNameThe group the analytics row summarizes
totalPostsAnalyzedNumber of posts collected this run for the group
topContributorsUp to 5 authors ranked by post count this run — [{authorId, authorName, postCount}]
postingCadenceEstimatePosts/day implied by the timestamp spread of posts collected this run; null if fewer than 2 timestamped posts or the span is zero
totalCommentsCollectedTotal comments + replies collected this run for the group
commentsPerPosttotalCommentsCollected / totalPostsAnalyzed, rounded to 3 decimals; null if there are no posts
scrapedAtISO-8601 UTC timestamp the row was built

🤖 Add-on: Need additional Facebook or community data?

If you also need public Facebook event listings, pair this with Facebook Events Scraper, which turns search keywords into structured event data (names, dates, locations, attendance signals). For a similar "who's active in this community" question on a different platform, Reddit Subreddit Members Scraper surfaces active subreddit participants the same way this Actor surfaces active Facebook group contributors via topContributors.

🛠️ Why not build this yourself?

Facebook's own Graph API does not offer a public, unauthenticated endpoint for arbitrary group posts and comments — group content access is limited to app-reviewed permissions scoped to groups your app manages, so it isn't a substitute for reading public content across many independent groups you don't administer.

Building this yourself means reverse-engineering Facebook's internal contracts and keeping up with their drift: this Actor resolves each group's internal ID and GraphQL query ID (doc_id) directly from the page's own HTML and JS bundles, because Facebook doesn't publish them; a secondary "load more comments" GraphQL pass is attempted for deeper comment coverage but can fail with Facebook's missing_required_variable_value error when Facebook's own variable contract shifts — a real, live-observed schema-drift condition, not a bug in the request. On top of that, every request needs a residential-proxy-backed session with retry and backoff logic to avoid anti-bot blocking. Facebook Group Posts Scraper maintains all of that so you don't have to.

🚀 How to use Facebook Group Posts Scraper

Run it directly from the Apify Store — no separate signup or API key beyond your Apify account is required.

  1. Open the Actor's page in Apify Console and click Try for free / Start.
  2. Add at least one entry to startUrls — a full group URL or a bare group identifier (required).
  3. Optionally set maxPosts, sortOrder, startDate, monitoringMode, and the comment/analytics toggles.
  4. Start the run.
  5. Download or stream results as JSON, CSV, Excel, or XML from the run's dataset, or pull them via the Apify API.

How to scale to bulk group extraction

startUrls accepts an array — add as many group URLs or identifiers as you need in a single run. maxPosts is one global cap: it's split evenly across every group in startUrls (with any remainder distributed one-by-one), each group's posts are collected against its own share, and the combined results are merged and capped again at your maxPosts value.

💡 What can you do with Facebook group data?

  • 📊 Community managers monitoring group health use topContributors and postingCadenceEstimate to see who's actually driving activity and how often the group posts, without opening it in a browser.
  • 🔬 Researchers studying group discourse use postText, text, and threadingDepth to reconstruct full comment trees for qualitative analysis.
  • 📈 Marketing teams use groupMemberCountApprox and commentsPerPost across multiple groups in one startUrls run to compare engagement levels before deciding where to run a campaign.
  • 🕵️ Lead researchers use postAuthor, postAuthorId, and postAuthorUrl to identify the members most active in a niche public group.
  • 🤖 AI engineers feed postText, text, and groupDescription into a RAG pipeline or an LLM summarizer to generate a digest of what a community group has been discussing.

🛡️ How does Facebook Group Posts Scraper handle rate limits and blocking?

Every request — group pages, post permalinks, and comment fetches — routes through Apify Proxy, defaulting to the residential proxy group; if a managed proxy session can't be created, the Actor retries up to 3 times before falling back to a direct connection with a logged warning. GraphQL and HTML requests retry up to 3 times with increasing backoff on connection errors and on retryable HTTP status codes (408, 429, 500, 502, 503, 504). Feed pagination for a group gives up after 8 consecutive pages produce no new posts or cursor movement, and group-metadata resolution (the group's internal ID and GraphQL query ID) is retried up to 4 times across Facebook's www/m/bare-domain URL variants before that group is treated as unreachable.

⚠️ One real limitation worth knowing: if a group's metadata can't be resolved after those retries, that failure is not isolated per group — it can end the whole run's post collection and gets logged as a temporary issue, since group fetching runs concurrently and an unhandled error from one group propagates to the run. Per-post comment fetches, by contrast, are isolated — a failed comment fetch just yields zero comments for that post, never a failed run.

⬇️ Input

ParameterRequiredTypeDescriptionExample Value
startUrlsYesarrayFacebook group URLs or bare group identifiers. Add multiple to scrape several groups in one run.["https://www.facebook.com/groups/cheapmealideas"]
maxPostsNointegerGlobal post cap across the whole run (minimum 10, default 10). With multiple startUrls, split across groups and the merged result is capped at this value.50
sortOrderNostring (enum: RECENT_POSTS, TOP_POSTS, RECENT_ACTIVITY, CHRONOLOGICAL)Sorting strategy for the group feed. Default RECENT_ACTIVITY."RECENT_ACTIVITY"
startDateNostring (date, YYYY-MM-DD)Only scrape posts newer than this date. Leave empty to scrape all available posts."2026-02-20"
monitoringModeNobooleanWhen true, remembers seen post IDs (via the Apify Key-Value Store) and skips duplicates on future runs. Default false.false
includeCommentsNobooleanFetch each post's comments + nested replies into a separate child dataset. Default true.true
maxCommentsPerPostNointegerCap on top-level comments collected per post (minimum 0, default 20). 0 disables comment fetching even if includeComments is on.20
maxRepliesPerCommentNointegerCap on nested replies collected per top-level comment (minimum 0, default 5). Ignored when includeComments is off.5
commentsSortOrderNostring (enum: all, newest, most_relevant)Order applied to top-level comments before the maxCommentsPerPost cap. Default all (original order). Nested reply order is not re-sorted — it follows Facebook's own rendering order."all"
includeEngagementAnalyticsNobooleanAdd one locally-computed analytics summary row per group. Default true.true
proxyConfigurationNoobjectApify Proxy settings, used for every request this Actor makes. Defaults to residential.{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}

Example input

{
"startUrls": [
"https://www.facebook.com/groups/cheapmealideas",
"germtheory.vs.terraintheory"
],
"maxPosts": 50,
"sortOrder": "RECENT_ACTIVITY",
"startDate": "2026-02-20",
"monitoringMode": false,
"includeComments": true,
"maxCommentsPerPost": 20,
"maxRepliesPerComment": 5,
"commentsSortOrder": "most_relevant",
"includeEngagementAnalytics": true,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}

⬆️ Output

Every row is typed, normalized JSON with a consistent schema across runs. Posts, comments, replies, and per-group analytics all land in the same default dataset (tagged by type and isChild), and comment/reply rows are additionally mirrored into a separate per-run child dataset. Results can be exported as JSON, CSV, Excel, XML, or RSS directly from the run's dataset in Apify Console, or pulled programmatically via the Apify API.

Every row pushed to the dataset — post, comment, reply, or analytics — is charged as one row_result event. Rows that fail to save due to a transient error are not written to the dataset at all, so there is no separate uncharged/error row type to filter out.

Example output

Post row:

{
"id": "28288689954096804",
"type": "post",
"isChild": false,
"parentId": null,
"postText": "Ground turkey cooked in a pan and then you add stir fry veggies...",
"postAuthor": "Jane Doe",
"postAuthorId": "100048765312428",
"postAuthorUrl": "https://www.facebook.com/profile.php?id=100048765312428",
"firstName": "Jane",
"lastName": "Doe",
"image": "https://scontent.xx.fbcdn.net/v/t39.30808-6/example.jpg",
"postUrl": "https://www.facebook.com/groups/cheapmealideas/posts/28288689954096804/",
"publishedAt": "2026-07-31T14:23:03Z",
"groupUrl": "https://www.facebook.com/groups/cheapmealideas",
"groupName": "Cheap Meal Ideas",
"groupVanity": "cheapmealideas",
"groupPrivacy": "Public group",
"groupMemberCountText": "6.0M members",
"groupMemberCountApprox": 6000000,
"groupDescription": "This group is open for anyone to join or share with others...",
"groupCreatedAt": null,
"groupCoverPhotoUrl": "https://scontent.xx.fbcdn.net/v/t39.30808-6/cover.jpg",
"scrapedAt": "2026-08-02T09:00:00Z"
}

Comment row (also written to the child dataset):

{
"id": "Y29tbWVudDoyODI4ODY4OTk1NDA5NjgwNF8yODMwMzk0MzM3NTkwNDc5NQ==",
"type": "comment",
"isChild": true,
"parentId": "28288689954096804",
"postId": "28288689954096804",
"postUrl": "https://www.facebook.com/groups/cheapmealideas/posts/28288689954096804/",
"groupUrl": "https://www.facebook.com/groups/cheapmealideas",
"threadingDepth": 0,
"feedbackId": "ZmVlZGJhY2s6MjgyODg2ODk5NTQwOTY4MDQ=",
"date": "2026-07-31T22:14:15Z",
"text": "Ground turkey cooked in a pan and then you add stir fry veggies...",
"profilePicture": "https://scontent.xx.fbcdn.net/v/t1.6435-1/profile.jpg",
"profileId": "100093827465210",
"profileName": "CarefreeLlama2513",
"profileUrl": null,
"likesCount": 2,
"repliesCount": 0,
"facebookId": "",
"scrapedAt": "2026-08-02T09:00:05Z"
}

Analytics row (one per group):

{
"id": "analytics-7f3a91c2b6d4e8a1",
"type": "analytics",
"isChild": false,
"parentId": null,
"groupUrl": "https://www.facebook.com/groups/cheapmealideas",
"groupName": "Cheap Meal Ideas",
"totalPostsAnalyzed": 30,
"topContributors": [
{ "authorId": "100048765312428", "authorName": "Jane Doe", "postCount": 4 }
],
"postingCadenceEstimate": 6.2,
"totalCommentsCollected": 187,
"commentsPerPost": 6.233,
"scrapedAt": "2026-08-02T09:04:11Z"
}

⚙️ How does it work?

Facebook Group Posts Scraper sends requests through Apify Proxy (residential by default) directly to Facebook's own public GraphQL endpoint and public HTML pages, using headers that mirror a real browser session — no headless browser rendering is used. Because Facebook doesn't publish stable identifiers for its internal group-feed and comment-pagination queries, the Actor resolves each group's internal ID and GraphQL query ID by scanning the group page's own HTML and linked JS bundles at request time, the same way a browser's own client would load them. Group profile fields (name, description, member count, cover photo) come from the same page fetch, parsed from Facebook's own embedded metadata rather than guessed. Only what an anonymous, logged-out visitor could see is ever returned, and the output field names stay the same run to run — they're derived from Facebook's own data structures, not from whatever the page happens to render visually.

🔌 Integrations

Facebook Group Posts Scraper runs on the Apify platform, so it works with everything already built around the Apify API.

Calling Facebook Group Posts Scraper programmatically

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_API_TOKEN>")
run_input = {
"startUrls": ["https://www.facebook.com/groups/cheapmealideas"],
"maxPosts": 30,
"includeComments": True,
}
run = client.actor("<your-username>/facebook-group-posts-and-details-scraper-comments-analytics").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

Works in Go, Ruby, Node.js, cURL — any language that can make an HTTP request.

No-code tools (n8n, Make)

In n8n, use the HTTP Request node (or the Apify node) pointed at this Actor's run endpoint on the Apify API to trigger a run and pull dataset items into your workflow. In Make, use Apify's HTTP module the same way — call the run endpoint, then fetch the resulting dataset items as the next step in your scenario.

Scraping publicly accessible Facebook group posts and comments is generally legal — this Actor only reads pages Facebook already serves to a logged-out, anonymous visitor, the same content anyone can see without an account. Facebook Group Posts Scraper returns only that publicly available data.

Because group posts and comments carry personal data about named individuals — post authors, commenters, and their profile links — storing or reusing this data can fall under data-protection law such as the EU/UK GDPR and the California CCPA, which require a lawful basis for collecting and retaining personal data regardless of whether the source was public. Facebook's Terms of Service separately restrict automated data collection. Consult legal counsel if your use case involves bulk storage of personal data.

❓ Frequently asked questions

What Facebook group post fields does Facebook Group Posts Scraper return?

The top fields are postText, postAuthor, postAuthorUrl, publishedAt, and groupMemberCountApprox — see What data can I extract for the full list across posts, comments, and analytics rows.

Does Facebook Group Posts Scraper require a Facebook account or login?

No. It reads public, logged-out group and post pages — no Facebook account, cookies, or API token are needed. The only credential involved is your Apify account for running the Actor.

How many posts can I extract in one run?

maxPosts has a minimum of 10 but no fixed maximum in the input schema. Internally, the Actor paginates a group's feed for at least 120 pages (scaling higher for larger requests) before giving up, and in monitoringMode it deliberately over-fetches — up to 2,500 raw posts per group — to reliably find unseen posts before applying your cap.

What happens if a group URL is private, invalid, or can't be resolved?

The Actor retries resolving that group's metadata up to 3 times before giving up on it. If it still can't be resolved, that error is not isolated to the failed group — because groups are fetched concurrently, it can end the entire run's post collection and gets logged as a temporary issue. Double-check that each startUrls entry points to a public group before running with several groups at once.

Can I scrape multiple Facebook groups at once?

Yes — add multiple entries to startUrls. maxPosts is a single total shared across all of them, split evenly (with remainders distributed one-by-one) before the merged results are capped again.

Does Facebook Group Posts Scraper work with Claude, ChatGPT, and other AI agent tools?

It's not exposed through a dedicated MCP server, but it's callable as a plain HTTP endpoint via the Apify API from any agent framework, tool-use setup, or client library that can make a request.

What makes this different from a basic Facebook group post scraper?

Unlike a scraper that only returns the post feed, Facebook Group Posts Scraper also fetches each post's comment thread — including nested replies — into a linked child dataset, and computes engagement analytics (topContributors, postingCadenceEstimate, commentsPerPost) locally from that same run's data, with no separate AI step or paid enrichment call.

Does Facebook Group Posts Scraper return data in a format LLMs can use directly?

Yes. Output is typed, normalized JSON with consistent field names across runs — no HTML parsing or CSS selectors required. Pass it directly to an LLM, index it into a vector store, or feed it to an agent tool.

What happens when Facebook changes its layout or anti-bot system?

Facebook Group Posts Scraper is actively maintained, and the output schema is designed to stay stable across Facebook's UI changes. No specific update turnaround time is published or guaranteed.

Can I use Facebook Group Posts Scraper without managing proxies or browser infrastructure?

Yes. Apify Proxy (residential by default) and retry/backoff logic are handled automatically. No browser is launched — requests go directly to Facebook's public GraphQL and HTML endpoints.

Which fields work best for AI training data and RAG indexing?

For RAG, index postText, text (comment/reply body), and groupDescription — the highest-information free-text fields. For training data, postAuthorId, likesCount, publishedAt, and threadingDepth return as consistently typed primitives across every row.

ScraperWhat it extracts
Facebook Events ScraperPublic Facebook events — names, dates, locations, attendance signals
Threads Search Post Scraper: Posts, Quotes & RepliesThreads posts, quotes, reposts, and nested reply threads
LinkedIn Profile Post ScraperPosts published on a LinkedIn profile, with likes/comments/shares
Reddit Subreddit Members Scraper (Active Participants)Active subreddit participants and commenters
Twitter (X.com) Tweets & Profiles ScraperTweets and profile data from X/Twitter

💬 Your feedback

Found a bug or missing a field? Let us know via the Actor's Issues tab in Apify Console, or through Apify's support chat — reports like this are exactly how the output schema stays accurate as Facebook's own group pages change.