πŸ“˜ Facebook Group Posts Scraper Pro avatar

πŸ“˜ Facebook Group Posts Scraper Pro

Pricing

$19.99/month + usage

Go to Apify Store
πŸ“˜ Facebook Group Posts Scraper Pro

πŸ“˜ Facebook Group Posts Scraper Pro

Facebook Group Post Scraper extracts posts from public Facebook groups, capturing text, images, videos, author details, timestamps, reactions, comments, and share data. Ideal for community research, trend analysis, social listening, and automating structured Facebook group post insights.

Pricing

$19.99/month + usage

Rating

0.0

(0)

Developer

SimpleAPI

SimpleAPI

Maintained by Community

Actor stats

1

Bookmarked

45

Total users

7

Monthly active users

16 days

Issues response

4 days ago

Last modified

Share

Facebook Group Scraper β€” Posts, Comments and Engagement Data

Facebook Group Posts Scraper Pro pulls posts from one or many public Facebook groups and returns them as structured JSON: post text, media attachments, per-reaction-type breakdowns (Like, Love, Care, Haha, Wow, Sad, Angry), share and comment counts, hashtags, mentions, and computed engagement figures. Turn on comment scraping and every comment and reply is pushed as its own linked row. Built for social listening teams, community managers, market researchers, and lead-gen pipelines that need group discussions as clean, queryable data rather than a scrolling feed.

What is Facebook Group Posts Scraper Pro?

Facebook Group Posts Scraper Pro is an Apify Actor that scrapes the public post feed of one or more Facebook groups β€” by URL, vanity name, or numeric group ID β€” and returns each post as a dataset row, with an optional second pass that fetches every comment and reply underneath it. No Facebook login is required for public groups; the Actor reverse-engineers Facebook's own web GraphQL feed and impersonates a real Chrome browser's TLS fingerprint to get accepted requests, so results come back in the same shape Facebook's website itself uses internally.

Key capabilities, read from the source:

  • Group discovery by URL, vanity name, or numeric ID β€” startUrls takes a list of any of the three; the Actor normalizes each into a canonical group URL before scraping.
  • Three feed orderings β€” newest-first (with an early pagination stop once you've paged past your date cutoff), most-relevant, and recent-activity, matching Facebook's own sort options.
  • Full comment and reply threads β€” comments are fetched via Facebook's own paginated comments API, and replies via a separate depth-1 replies query, each capped independently.
  • Reaction, share, and comment counts, plus computed engagement β€” per-type reaction breakdown, total engagement, and (when the group's member count is discoverable) an engagement rate.
  • Server-side filtering on parent posts β€” keyword include/exclude, post type (text/photo/video/link), and a minimum-reactions threshold, all applied before a row is charged.
  • Optional session cookie for closed groups you already belong to (experimental; public groups don't need it).

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

The Actor pushes two kinds of rows to the same dataset β€” type: "post" for parent posts and type: "comment" / type: "reply" for child rows β€” distinguished by the isChild flag. The dataset's default table view surfaces 24 columns, but the Actor pushes a few extra keys per row that aren't in that view; every one is documented below, straight from the row-building functions in src/helper.py.

FieldRow typeDescription
typeall"post", "comment", or "reply"
isChildallfalse for posts, true for comments and replies
postIdpost, comment, replyFacebook's post ID
feedbackIdpost (not in default view)Internal Facebook feedback token used to paginate that post's comments
commentIdcomment, replyFacebook's comment ID (falls back to the internal node ID if no legacy ID exists)
parentIdallnull on posts; the post ID on comments; the parent comment ID on replies
groupIdallFacebook's numeric group ID
groupNameallGroup display name, parsed from the group page's <title> tag
groupUrlall (not in default view)The normalized group URL you supplied as input
urlpost, comment, replyPost permalink on posts; the comment/reply's direct link on comment rows (can be null)
postUrlcomment, reply (not in default view)Direct permalink of the parent post
createdAtallUnix seconds
publishedAtallISO-8601 UTC, derived from createdAt
textallPost, comment, or reply text
depthcomment, reply (not in default view)Facebook's own nesting-depth value for the comment node
hashtagspost onlyHashtags parsed from the post's message entity ranges (with a regex fallback)
mentionspost only{ name, id, url, type } for each @-mentioned user, page, or group
attachmentspost onlyParsed media list β€” see below
userall{ id, name, url, type, profilePicture } on posts; { id, name, url, gender, profilePicture } on comments/replies
reactionCountallTotal reactions, or null if Facebook didn't return a count
reactionsallPer-type breakdown, e.g. { "Like": 51, "Love": 2, "Care": 2 }
shareCountpost onlyTotal shares, or null
commentCountpost onlyTotal comments Facebook reports for the post, or null
replyCountcomment, replyReplies under this comment, or null
engagementTotalpost onlyreactionCount + shareCount + commentCount, summing only the values that are integers
engagementRatepost onlyengagementTotal / group member count, rounded to 6 decimals β€” null when the member count couldn't be parsed from the group page
postAgeHourspost onlyHours between the post's createdAt and the moment it was scraped
scrapedAtallISO-8601 UTC timestamp of the scrape

Attachments and reactions

Each entry in attachments is { type, url, image, width, height, title, accessibilityCaption, mediaId }, with an optional description key when Facebook returns one. type is photo, video, link, album, or a best-guess fallback derived from Facebook's own style list; multi-photo albums are flattened so each photo in the album becomes its own attachment entry. reactions decodes Facebook's opaque reaction IDs into names using a fixed map of the eight standard reaction types (Like, Love, Care, Haha, Wow, Sad, Angry, Thankful) β€” any reaction ID outside that map is emitted as reaction_<id> rather than dropped or guessed at.

Filtering fields

postType, minReactions, keywords, and excludeKeywords are applied against text and attachments on parent posts only, before the post is pushed β€” a post that fails a filter is never charged. Comments and replies are not filtered by these same options; once includeComments is on, every comment (and reply, if maxReplies is set) under a passing post is fetched.

Why not build this yourself?

Facebook does not expose group post content, comments, or reactions through a stable public API that a third-party tool can call with a client ID and get structured JSON back. Building this yourself means reverse-engineering Facebook's internal web GraphQL feed β€” the same interface src/main.py implements: harvesting LSD and DTSGInitialData tokens from the group's HTML, locating the current persisted-query doc_id values for the feed, comments, and replies queries (which Facebook rotates, so the Actor scans the group's own JS bundles for them when its fallback IDs go stale), and assembling each request with the right Relay variables and headers so it isn't rejected as a bot.

On top of that, Facebook fingerprint-blocks plain HTTP clients on this endpoint β€” the Actor uses curl_cffi with Chrome TLS/JA3 impersonation specifically because standard requests/aiohttp calls get refused, and it rotates through fresh residential proxy IPs (up to 14 attempts per group) until a group's feed responds with real posts, since Facebook blocks datacenter IPs on group feeds outright. None of this is a one-off script; it's the ongoing maintenance burden the Actor absorbs so you don't have to track Facebook's query IDs and anti-bot behavior yourself.

How to use data extracted from Facebook groups?

Social media and community managers

Set startUrls to the groups you run or watch, sortType: "recent_activity" to surface what's trending, and includeComments: true with a modest maxComments to pull sentiment straight from the thread. The reactions breakdown and engagementTotal field let you rank posts by what's actually resonating, without opening Facebook.

Social listening and brand-monitoring agencies

Point the same run at every group you monitor on a client's behalf, using keywords to isolate brand or competitor mentions and excludeKeywords to drop noise like giveaway posts. Because groupName and groupId are tagged on every row, one run across multiple groups still segments cleanly per client or per community in your downstream reporting.

Market research and intelligence

Use scrapeUntil with a relative value like "7 days" on sortType: "new_posts" to pull a rolling week of discussion from category-relevant groups (parenting groups, niche hobby groups, local buy-sell groups), then aggregate hashtags, postType-filtered subsets, and reactionCount distributions to track what topics and formats a community engages with over time.

AI agents and automated pipelines

Because every row is typed JSON with a stable schema, a scheduled run's dataset can feed directly into a RAG index or an LLM summarization pipeline β€” text, reactions, and commentCount per post give an agent enough signal to rank or summarize group activity without any HTML parsing on the agent's side.

πŸ”½ Input sample

Every field below matches .actor/actor.json exactly β€” same names, same types, same defaults. Nothing is required; an empty input run will error out (see the pitfall note below).

ParameterTypeDefaultConstraintsDescription
startUrlsarrayβ€”β€”One or more Facebook group URLs, vanity names, or numeric group IDs. Each row is tagged with its source group.
groupUrlstringβ€”β€”Optional single-group input, kept for backward compatibility. Merged with startUrls if both are set.
countinteger20min 0, max 100000Maximum number of parent posts to collect across all groups. Comments/replies don't count against it. 0 = unlimited.
sortTypestring (enum)"new_posts"new_posts, most_relevant, recent_activityHow Facebook orders the feed. new_posts is newest-first and enables the date early-stop below.
scrapeUntilstring (date)β€”absolute (2026-01-15) or relative ("7 days", "2 weeks", "3 months")Keep only posts created on/after this date, UTC. On new_posts sort, pagination stops early once older posts are reached.
includeCommentsbooleanfalseβ€”Fetch each post's comments as separate child rows, mirrored to a per-run comments dataset.
maxCommentsinteger0min 0, max 1000Cap of comments fetched per post. 0 = none, unless includeComments is on, in which case comments are effectively uncapped (see the note below).
maxRepliesinteger0min 0, max 500Cap of replies fetched per comment. 0 = skip replies entirely.
keywordsarrayβ€”β€”Keep only posts whose text contains at least one term (case-insensitive OR).
excludeKeywordsarrayβ€”β€”Drop posts whose text contains any of these terms.
postTypestring (enum)"any"any, text, photo, video, linkKeep only posts of this media type. text keeps posts with no attachment at all.
minReactionsinteger0min 0Keep only posts with at least this many total reactions.
minDelayinteger1min 0, max 60Minimum delay (seconds) between paginated feed requests.
maxDelayinteger3min 0, max 120Maximum delay (seconds) between paginated feed requests. Auto-raised to match minDelay if you set it lower.
cookiestring (secret)β€”β€”Experimental. Raw Cookie header from a logged-in session ("c_user=...; xs=...; datr=..."), for closed groups you're a member of.
proxyobject{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}β€”Proxy configuration. Residential is the default and is strongly recommended β€” Facebook blocks datacenter IPs on group feeds.
{
"startUrls": ["https://www.facebook.com/groups/cheapmealideas"],
"count": 50,
"sortType": "new_posts",
"scrapeUntil": "7 days",
"includeComments": true,
"maxComments": 20,
"maxReplies": 5,
"keywords": ["recipe", "budget"],
"postType": "any",
"minReactions": 3,
"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}

Common pitfall: if you leave both startUrls and groupUrl empty, the run logs "No group URL provided. Set 'startUrls' or 'groupUrl'." and exits immediately with zero rows charged. A second one: keywords, excludeKeywords, postType, and minReactions only filter parent posts β€” they don't filter which comments or replies come back once includeComments is on, so a post that barely clears your minReactions threshold can still bring its full comment thread with it.

πŸ”Ό Output sample

Every row lands in the run's default dataset, exportable as JSON, CSV, Excel, or the other formats Apify's Dataset tab offers. When includeComments or maxComments is set, comment and reply rows are also mirrored into a separate per-run dataset named comments-<RUN_ID>, in addition to being interleaved into the default dataset right after their parent post.

A parent post row:

{
"type": "post",
"isChild": false,
"parentId": null,
"postId": "1234567890123456",
"feedbackId": "ZmVlZGJhY2s6MTIzNDU2Nzg5MDEyMzQ1Ng==",
"groupId": "1745271899086274",
"groupName": "Cheap Meal Ideas",
"groupUrl": "https://www.facebook.com/groups/cheapmealideas",
"url": "https://www.facebook.com/groups/1745271899086274/permalink/1234567890123456/",
"createdAt": 1753500000,
"publishedAt": "2026-07-26T09:20:00Z",
"text": "Made a huge batch of lentil soup for $8 total β€” recipe in comments!",
"hashtags": ["budgetmeals"],
"mentions": [],
"attachments": [
{
"type": "photo",
"url": "https://www.facebook.com/photo/?fbid=1234567890",
"image": "https://scontent.fplu1-1.fna.fbcdn.net/v/example.jpg",
"width": 960,
"height": 720,
"title": null,
"accessibilityCaption": "A pot of orange soup on a stovetop",
"mediaId": "1234567890"
}
],
"user": {
"id": "10001",
"name": "Jane Doe",
"url": "https://www.facebook.com/jane.doe",
"type": "User",
"profilePicture": "https://scontent.fplu1-1.fna.fbcdn.net/v/profile.jpg"
},
"reactionCount": 55,
"reactions": { "Like": 51, "Love": 2, "Care": 2 },
"shareCount": 3,
"commentCount": 12,
"engagementTotal": 70,
"engagementRate": 0.005833,
"postAgeHours": 4.32,
"scrapedAt": "2026-07-26T13:32:00Z"
}

A child comment row (pushed only when includeComments or maxComments is set):

{
"type": "comment",
"isChild": true,
"commentId": "987654321012345",
"parentId": "1234567890123456",
"postId": "1234567890123456",
"postUrl": "https://www.facebook.com/groups/1745271899086274/permalink/1234567890123456/",
"groupId": "1745271899086274",
"groupName": "Cheap Meal Ideas",
"groupUrl": "https://www.facebook.com/groups/cheapmealideas",
"url": "https://www.facebook.com/groups/1745271899086274/permalink/1234567890123456/?comment_id=987654321012345",
"createdAt": 1753500600,
"publishedAt": "2026-07-26T09:30:00Z",
"text": "Here's the recipe: 2 cups lentils, 1 onion, 2 carrots, veg stock...",
"depth": 0,
"user": {
"id": "10002",
"name": "Mark Alvarez",
"url": "https://www.facebook.com/mark.alvarez",
"gender": "MALE",
"profilePicture": "https://scontent.fplu1-1.fna.fbcdn.net/v/profile2.jpg"
},
"reactionCount": 6,
"reactions": { "Like": 5, "Love": 1 },
"replyCount": 2,
"scrapedAt": "2026-07-26T13:32:01Z"
}

Reply rows use the same shape as comment rows, with type: "reply" and parentId set to the parent comment's commentId instead of the post ID.

How do you filter and target specific posts?

This Actor doesn't search Facebook by keyword β€” it always starts from a group you name β€” so precision targeting comes from four knobs working together rather than a query string.

  1. Group targeting. startUrls accepts a full URL, a bare vanity name, or a numeric group ID, and normalizes any of the three into a canonical group URL, so you can mix formats freely across a list of groups in one run.
  2. Time scope. scrapeUntil bounds a run by date β€” absolute ("2026-06-01") or relative ("2 weeks"). Pair it with sortType: "new_posts" and pagination stops as soon as it crosses your cutoff, which keeps a scheduled daily or weekly run cheap and fast instead of re-walking the whole feed every time.
  3. Quality thresholds. minReactions drops low-engagement posts before they're charged, and postType narrows to text-only, photo, video, or link posts β€” useful when you only want, say, the photo posts in a marketplace-style group.
  4. Volume controls. count caps parent posts per run (0 = unlimited); maxComments and maxReplies independently cap the comment thread depth pulled per post, so a run with count: 20 and maxComments: 5 never charges more than 20 posts plus up to 100 comment rows, regardless of how deep the real threads go.
{ "startUrls": ["https://www.facebook.com/groups/localbuysell"], "postType": "photo", "minReactions": 10, "count": 30 }
{ "startUrls": ["https://www.facebook.com/groups/cheapmealideas"], "sortType": "new_posts", "scrapeUntil": "3 days", "keywords": ["recipe"] }
{ "startUrls": ["https://www.facebook.com/groups/1745271899086274"], "includeComments": true, "maxComments": 50, "maxReplies": 10, "count": 10 }

▢️ Want to try other Facebook scrapers?

ScraperWhat it extracts
Facebook Groups Search Scraper PlusDiscovers Facebook groups by keyword and enriches results with member counts, activity level, and privacy status
Facebook Groups Posts & Comments Scraper (pay-per-events)A pay-per-event variant covering the same group posts-and-comments use case
Facebook Photos ScraperExtracts photos from a Facebook profile or page, with real dimensions, captions, and engagement counts
Instagram Followers ScraperScrapes the followers list of an Instagram account
Instagram Profile Contact EnricherEnriches Instagram profiles into contact rows β€” business phone/email, category, and validated bio contacts
LinkedIn Profile Contact LookupLooks up contact details for LinkedIn profiles

How to extract Facebook group data programmatically

The Actor runs like any other Apify Actor: start it through the Console, on a schedule, via a webhook, or through the Apify API/SDK with your Apify API token. There's no separate signup or API key beyond your Apify account.

Python example

from apify_client import ApifyClient
client = ApifyClient("<APIFY_API_TOKEN>")
run = client.actor("facebook-group-posts-scraper-pro").call(run_input={
"startUrls": ["https://www.facebook.com/groups/cheapmealideas"],
"count": 50,
"includeComments": True,
"maxComments": 10,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["type"], item.get("text", "")[:80], item.get("reactionCount"))

Export to spreadsheets or CRM

Every dataset row is flat enough to export directly: use the Dataset tab's CSV or Excel export, and map text, user.name, groupName, reactionCount, and url to your CRM's note, contact-name, source, and link fields β€” nested keys like user and reactions export as JSON strings in CSV, so pull user.name/user.url via a quick post-processing step if your CRM needs them as separate columns.

Scraping publicly accessible Facebook group content β€” posts that any logged-out visitor to a public group can see β€” is generally lawful; this Actor does not access private or closed groups unless you supply your own session cookie for a group you already belong to. Each row does contain personal data (post and comment authors' names, profile URLs, and profile pictures), so GDPR and CCPA apply to how you store and use it, not to the act of collecting public posts itself: you need a lawful basis (typically legitimate interest) for retaining that personal data, and you should honor deletion/access requests from individuals identified in your dataset. Consult legal counsel for commercial applications involving bulk storage of personal data.

❓ Frequently asked questions

What happens if a post is later deleted from the group?

The Actor has no way to detect deletions after the fact β€” it returns whatever the group's feed serves at the moment of the run. A previously scraped row stays in your dataset even if the post is later removed by its author or a moderator; run the Actor again on a schedule if you need to track that kind of drift.

Can I get comments and replies along with the posts?

Yes. Set includeComments: true (or set maxComments above 0) and each post's comments come back as separate child rows, with maxReplies optionally pulling reply threads underneath each comment. Child rows are pushed to the same dataset as the posts, interleaved right after their parent, and also mirrored to a separate comments-<RUN_ID> dataset for the run.

How accurate is the reaction and comment data?

The Actor returns the counts exactly as Facebook's own feed API reports them at request time β€” it does not recompute or estimate anything. Because group activity changes continuously, treat counts as a snapshot as of scrapedAt, and re-run on a schedule if you need current numbers.

How many posts and comments can I get per run?

count caps parent posts per run, from 0 (unlimited) up to 100,000. maxComments caps comments per post up to 1,000 β€” but leaving it at 0 while includeComments is on removes that cap entirely, bounded only by an internal 60-page pagination guard rather than a fixed number. maxReplies caps replies per comment up to 500, and 0 skips replies outright.

Can I target specific kinds of posts within a group?

Yes β€” postType narrows to text-only, photo, video, or link posts, minReactions filters out low-engagement posts, and keywords/excludeKeywords include or exclude posts by text content. All four apply to parent posts only, before the row is charged.

Does Facebook Group Posts Scraper Pro work with Claude, ChatGPT, and AI agent frameworks?

It's not exposed through an MCP server. Any agent framework that can call the Apify API or the apify-client SDK β€” which covers Claude, ChatGPT, and custom agent stacks alike β€” can start a run and read the resulting dataset as a normal HTTP call.

How does this compare to other Facebook group scrapers?

As observed on the Apify Store on 2026-07-26, logical_scrapers' Facebook group posts scraper caps runs at 50 group URLs and uses a lightweight Cheerio (HTTP-only) engine with an optional Notion output, but does not document comment or reply extraction. memo23's Facebook Group Posts and Details Scraper requires a logged-in session cookie even for public groups and bills on a flat monthly price rather than pay-per-event. cleansyntax's scraper targets Facebook profiles rather than groups. This Actor is group-specific, requires no login for public groups, and returns full comment and reply threads as linked child rows alongside per-type reaction breakdowns.

Can I use this without a Facebook account or API key?

Yes, for public groups β€” no Facebook login, API key, or developer account is required; the Actor only needs your Apify account and a group URL. The cookie input is optional and experimental, used only when you want to reach a closed group you're already a member of.

Conclusion

Facebook Group Posts Scraper Pro turns any public Facebook group into a structured, filterable dataset β€” posts, full comment and reply threads, per-type reactions, and computed engagement, all under one consistent schema. It's built for teams who need group discussion as data: social listening, community management, market research, and AI pipelines that would otherwise be stuck copy-pasting a Facebook feed. Run it from the Apify Console or schedule it against the groups you track, and point your dashboard, spreadsheet, or agent at the dataset it produces.