Facebook Groups Posts Scraper
Pricing
from $0.60 / 1,000 posts
Facebook Groups Posts Scraper
Scrape the posts of public Facebook groups, newest first, no account needed: text, author, date, reactions by type, comments, photos, videos, links, sale listings. Filters by date, keywords and reactions, new posts only. Export to JSON, CSV or Excel.
Pricing
from $0.60 / 1,000 posts
Rating
0.0
(0)
Developer
Nice Dev
Maintained by CommunityActor stats
0
Bookmarked
72
Total users
33
Monthly active users
2 days ago
Last modified
Categories
Share
💬 What is Facebook Groups Posts Scraper?
Facebook Groups Posts Scraper extracts posts from public Facebook groups: text, author, date, reactions by type, comments, photos, videos, links and buy-and-sell listings, newest first. It works as a Facebook Groups API alternative: run it on a schedule, call it from your code, or plug it into Make, Zapier or n8n.
Paste a group URL (or type its ID or name), click Start, and download the posts in JSON, CSV or Excel. No Facebook account needed for public groups, nothing to set up: the proxy is included in the price.
📋 What data can you extract from Facebook groups?
One item per post, 42 fields:
| Category | What you get |
|---|---|
| 📝 Post | full text, link to the post, type (photo, album, video, link, shared…), hashtags, people tagged — Meet Archie, a one-year-old beagle mix |
| 👤 Author | name, profile link, profile photo, verified badge |
| 🕒 Date | publication time, exact to the second — 2026-10-06T01:00:58.000Z |
| ❤️ Engagement | reactions in total and by type (like, love, care, haha, wow, sad, angry), comment and share counts — 243 reactions, 19 comments, 5 shares |
| 💬 Comments | the 1-3 comments Facebook shows under each post, free; as an option, every comment and its replies |
| 📷 Photos and videos | full-size photo links, photo descriptions, direct video link, link cards; as an option, every photo of an album |
| 🛒 Buy and sell | title, price, currency, sold or not, item description; as an option, where the item is (city, place, coordinates) |
| 📞 Contacts | as an option, e-mail addresses and phone numbers written in the post, and the WhatsApp or Messenger button |
| 👥 Group | group name, ID and link; as an option, exact member count, posts per day, creation date, rules and admins |
Every field, with an example, is listed in the Output section below.
✅ Why use Facebook Groups Posts Scraper?
- 🔓 No account, no cookies: paste the link of a public group and start.
- 🗂️ Many groups in one run: up to 1,000 groups, with a cap per group so that one busy group cannot eat the whole budget. The same group pasted twice (by link, ID, name or a post URL) is read once.
- 🎯 Filters you rarely find elsewhere: keywords, minimum reactions, minimum comments, posts with a contact only, before / after a date, buy-and-sell listings only.
- 🔔 Monitoring built in: tick Only new posts, schedule the Actor, and each run returns (and charges) only the posts it has never delivered before.
- 💬 Every comment and reply, every photo of an album, where each item for sale is, group details and contacts: options you tick only when you need them, charged only when delivered.
- 🔌 API, scheduling, integrations (Make, Zapier, n8n, Google Sheets…) and JSON/CSV/Excel export via the Apify platform.
🚀 How to scrape Facebook groups
- Create a free Apify account.
- Open Facebook Groups Posts Scraper and paste one or more group links into Facebook groups (e.g.
https://www.facebook.com/groups/selftaughtprogrammers/), or type group IDs or names into Group IDs or names. The link from Facebook's Share / Copy link button (https://www.facebook.com/share/g/…) works as well. - Set Max posts (100 by default, 0 = no limit) — and Max posts per group when you read several groups.
- Tick the options you want (all comments, complete albums, item locations, group details, contacts) and the filters, then click Start.
- Download the dataset in JSON, CSV, Excel or via API.
💰 How much does it cost to scrape Facebook groups?
This Actor uses pay per event pricing: you pay per post saved, plus a small fee per run start. Higher Apify plans pay less. The options are off by default and charged only when they deliver something:
| What | Free | Bronze | Silver | Gold |
|---|---|---|---|---|
| 📝 Post saved (one row) | $0.63 per 1,000 | $0.62 | $0.61 | $0.60 |
| 🚀 Run start | $0.01 per run | $0.01 | $0.01 | $0.01 |
| 🔎 Filter check: a post read and dropped by one of your filters (keywords, reactions, comments, contact, listings only; the dates: only a post without a date) | $0.59 per 1,000 | $0.58 | $0.57 | $0.56 |
| 💬 Comment or reply saved (option All comments) | $0.54 per 1,000 | $0.51 | $0.45 | $0.32 |
| 📷 Complete album: an album completed past the photos of the feed (option Complete albums) | $1.39 per 1,000 albums | $1.38 | $1.37 | $1.36 |
| 📍 Listing location: an item for sale saved with its location (option Listing location) | $0.78 per 1,000 | $0.77 | $0.76 | $0.75 |
| 📞 Contact found: a post where an e-mail or a phone number was found, WhatsApp button included (option Contacts found in posts) | $7.19 per 1,000 posts with a contact | $7.18 | $7.17 | $7.16 |
| 👥 Group details, once per group (option Group details) | $10.99 per 1,000 groups | $9.59 | $8.39 | $7.19 |
Examples:
- 1,000 posts of one group on the Gold plan: $0.60 + $0.01 = $0.61 ($0.64 on the Free plan).
- 200 posts with All comments, 5 comments per post on average, on the Gold plan: $0.12 for the posts + $0.32 for the 1,000 comments + $0.01 = $0.45.
- A daily monitor (Only new posts) that finds 30 new posts a day on the Free plan: about $0.03 a day, $0.87 a month.
A post a filter keeps costs its normal price, a post a filter drops costs only the filter check. Facebook has no search inside a group without a login, so a rare keyword reads far back and pays the filter check on each post it drops: add Posted after to bound it. A post Only new posts already delivered costs nothing, and a group that gives no post is never charged for its details. Platform usage (compute, proxy) is included in the price.
⚙️ Input
The simplest run, one group:
{"startUrls": [{ "url": "https://www.facebook.com/groups/selftaughtprogrammers/" }],"maxItems": 200}
Several groups, a cap per group, last week only, posts that mention a job:
{"startUrls": [{ "url": "https://www.facebook.com/groups/selftaughtprogrammers/" }],"groupIds": ["dogspotting", "1010440649638729"],"maxItemsPerQuery": 100,"postedAfter": "7 days","keywords": ["hiring", "job offer"],"minReactions": 5}
Items for sale with where they are, in a buy-and-sell group:
{"startUrls": [{ "url": "https://www.facebook.com/groups/chothuenhanguyencannhatrang/" }],"maxItems": 50,"onlyListings": true,"includeListingLocation": true}
Every comment and reply, complete albums, group details, only new posts on each scheduled run:
{"startUrls": [{ "url": "https://www.facebook.com/groups/dogspotting/" }],"maxItems": 50,"includeComments": true,"includeReplies": true,"expandAlbums": true,"includeGroupDetails": true,"onlyNew": true,"stateKey": "dogspotting-daily"}
| Field | Notes |
|---|---|
startUrls | Group links (https://www.facebook.com/groups/selftaughtprogrammers/), the link of a post of the group (the whole group is read), or a share link (https://www.facebook.com/share/g/1AbCdEfGhI/, from Facebook's Share / Copy link button: the run follows it to the group; a share link that leads to a profile, a page or a private group is skipped with a message and listed in FAILED_REQUESTS, the other groups are read; paste the address your browser shows, which starts with https://www.facebook.com/groups/, instead). |
groupIds | Group IDs (387875758242831) or names (selftaughtprogrammers), when you have no link. Up to 1,000 groups with startUrls; a group given twice, by link, ID or name, is read once. |
maxItems, maxItemsPerQuery | Stop after this many posts for the whole run (0 = unlimited); cap for EACH group (0 = no per-group cap). |
postedAfter, postedBefore | Publication date range: 2026-09-01, or a period before now (7 days, 2 weeks, 1 month, 24 hours). |
keywords, excludeKeywords | Keep the posts whose text contains one of these words (hiring); drop those that contain one of the others. Case and accents ignored. The group is read post by post (no search without a login): a rare word reads far back (about 12,000 posts with maxItems 100, the whole group with 0), each dropped one charged the filter fee — add postedAfter to bound it. |
minReactions, minComments | Only posts with at least this many reactions / comments (0 = no minimum). |
onlyListings | Groups with a sale section: only the items for sale, with their price. Some groups have no listings feed: such a group is skipped with a message that says so (clear this option to read its posts), and the other groups are read. |
extractContacts, onlyWithContact | Find e-mail addresses and phone numbers in the posts (option); keep only the posts that have one (onlyWithContact needs extractContacts: without it the run is refused). |
includeComments, maxCommentsPerPost, includeReplies, maxRepliesPerComment | Every comment of each post (option), up to maxCommentsPerPost (100 by default); with includeReplies, the replies under each comment too and the replies to those replies, up to maxRepliesPerComment for each (includeReplies needs includeComments: alone it reads nothing and costs nothing). |
expandAlbums | Every photo of an album: Facebook shows only 5 in the group (option). |
includeListingLocation | Where each item for sale is: city, state, place and coordinates (option; one extra page read per item). |
includeGroupDetails | The group's About page once per group: exact member count, posts per day, creation date, privacy, rules (option). |
onlyNew, stateKey, resetState | Monitoring: only the posts never delivered under this memory key; resetState forgets the memory. |
| Advanced | proxyConfiguration (included in the price, leave the default), maxConcurrency (groups read at the same time), maxRequestsPerMinute, minRequestIntervalMs, maxRequestRetries, debugLog. |
📦 Output
A post, shortened (long texts and photo links cut, some columns left out):
{"id": "10166280720354467","url": "https://www.facebook.com/groups/dogspotting/posts/10166280720354467/","text": "Ever wonder what would happen if a beagle approached a German shepherd at a college mixer… meet Archie, a one-year-old…","publishedAt": "2026-10-06T01:00:58.000Z","postType": "album","user": { "id": "100001234567890", "name": "Jane Doe", "url": "https://www.facebook.com/jane.doe", "type": "User" },"groupId": "10487409466","groupTitle": "Dogspotting","groupUrl": "https://www.facebook.com/groups/dogspotting/","inputUrl": "https://www.facebook.com/groups/dogspotting/","reactionsCount": 243,"commentsCount": 19,"sharesCount": 5,"topComments": [{"id": "10166280811924467","text": "I once met a GSD x corgi and he looked the same, just shorter","publishedAt": "2026-10-05T19:44:05.000Z","authorName": "John Smith","depth": 0}],"comments": null,"images": ["https://scontent.xx.fbcdn.net/v/t39.30808-6/839389526_….jpg"],"imagesCount": 8,"attachments": [{ "type": "photo", "id": "10163808721866298", "url": "https://www.facebook.com/photo/?fbid=10163808721866298" }],"hashtags": [],"mentions": [],"emails": [],"phones": [],"groupDetails": null,"scrapedAt": "2026-10-06T12:00:00.000Z"}
You can download the dataset in various formats such as JSON, HTML, CSV or Excel.
All 42 fields
| Fields | What you get |
|---|---|
id, url, storyId, feedbackId | Post: Facebook's post ID, link to the post, and the two internal IDs other Facebook tools ask for |
text, postType, hashtags, mentions | the full text (null for a photo without text), photo / album / video / link / shared / text…, the hashtags, the people and pages tagged (name, id, link) |
publishedAt, timestamp | Date: ISO 8601 UTC and Unix seconds (for groups that approve posts, the time of approval) |
user | Author: id, name, profile link, type (User or Page), profile photo, verified badge — Anonymous participant for anonymous posts |
groupId, groupTitle, groupUrl, inputUrl | Group: ID, name, link, and the group as you gave it |
reactionsCount, reactionLikeCount, reactionLoveCount, reactionCareCount, reactionHahaCount, reactionWowCount, reactionSadCount, reactionAngryCount | Reactions: in total and by type (null when Facebook does not send the count, never a made-up 0) |
commentsCount, sharesCount | comment and share counts |
topComments | the 1-3 comments Facebook shows under the post: id, link, text, date, author name, ID and profile link — always filled, free |
comments | with includeComments: every first-level comment, the same fields plus reactions and reply count, and its replies with includeReplies (each reply holds its own replies, the second level); null when off |
images, imagesCount | full-size photo links in the album's order; how many photos Facebook says the post has (complete with expandAlbums) |
attachments, videoUrl | each photo, video or link card (size, photo description, video length, thumbnail…); direct MP4 link of the first video (expires after a few days) |
link, linkDomain, linkTitle, linkDescription | the outside link shared in the post (Facebook redirect removed) and its card |
actionLink | Contacts: the button the author added (WhatsApp, Messenger or a link, with its title and URL), with extractContacts; null without it |
listing | Buy and sell: id, title, price as shown, amount, currency, price type, sold or not, description, and with includeListingLocation its location (city, state, the place as the seller shows it, latitude, longitude; null when off) |
sharedPost | the post this one shares: id, link, text, author, and its photos (images, imagesCount; they are not in the row's own images) |
emails, phones | Contacts found in the text and in the WhatsApp button, with extractContacts |
groupDetails | with includeGroupDetails: member count, members text, posts in the last day and month, creation date, privacy, visibility, description, location, cover photo, admins, rules |
scrapedAt | ISO timestamp of the extraction |
💡 Tips
How to get more posts
Set Max posts to 0 and add more groups. Facebook serves a group's posts newest first: an old post is reached by reading every newer one before it, so a date filter (postedAfter) is the cheapest way to read only a period.
How to reduce costs
You pay per post, so the levers are maxItems, maxItemsPerQuery, the filters (a dropped post costs only the filter fee, lower than a post — but a word that rarely appears makes the run read far back in the group: about 12,000 posts with Max posts 100, the whole group with no cap; each dropped one is charged — bound it with postedAfter) and onlyNew for recurring runs (you never pay twice for the same post). Tick an option only when you need it: comments, albums, item locations, group details and contacts are charged only when they deliver.
Monitoring: only the new posts
Tick Only new posts (onlyNew) and schedule the Actor. The first run returns everything; each later run stops reading a group at the first post it has already delivered to you: older posts are neither saved nor charged. With filters, the group also stops at the first post that a previous run already read and dropped with the same filters, so a monitoring run does not read the whole group again. A post that does not pass a time-dependent filter yet (a relative "posted before" date) is checked again on the next run. The memory lives in a named key-value store of your account (facebook-groups-posts-scraper-seen, up to 150,000 posts per key) and is only updated with posts that really reached the dataset, so a failed run never hides anything. Give each schedule its own stateKey (two schedules sharing a key would hide each other's posts), and tick resetState once to start over. A first run capped by Max posts keeps its oldest posts out for good: for a complete history, run once without a cap, then schedule.
Filter by publication date
postedAfter and postedBefore take a date (2026-09-01, the whole day is included) or a period before now (7 days, 2 weeks, 1 month; via the API also 24 hours or a full ISO date-time). The filter reads publishedAt. Posts come newest first, so a group stops at the first post older than postedAfter; posts newer than postedBefore are read and skipped. Posts outside the dates are not saved, not charged and do not count in maxItems; only a post without a date is dropped with the filter fee (see Pricing).
🔌 Integrations and API
Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.
🤖 Use with AI agents (MCP)
AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the Apify MCP server, billed to their Apify account like any run. It returns one item per post of a public Facebook group. Actor id: nice_dev/facebook-groups-posts-scraper; MCP server with this Actor only: https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/facebook-groups-posts-scraper.
Smallest input, for a cheap first call:
{"startUrls": [{ "url": "https://www.facebook.com/groups/selftaughtprogrammers/" }],"maxItems": 10}
Key output fields: url, text, publishedAt, user, reactionsCount, commentsCount, images, groupTitle.
Cost: per post saved plus a small run-start fee, see the pricing section above. Cap each call with maxItems and, through the API, with the run option maxTotalChargeUsd.
❓ FAQ
Is it legal to scrape Facebook groups?
The Actor only reads what Facebook shows publicly to any anonymous visitor of a public group. It logs in to nothing. Results contain personal data (names, profile links, and with the option e-mail addresses and phone numbers written in posts), which is protected by GDPR and similar laws: do not store it without a legitimate reason. You are responsible for using the data in compliance with Facebook's Terms of Service and applicable law. This Actor is not affiliated with Meta or Facebook.
Does it need a login or a proxy?
No login for public groups. The proxy is included in the price: leave the default setting. A request Facebook turns away is retried at once on a new proxy session, up to 10 times on top of the retries (without a proxy, after a pause of 5 seconds, doubled at each retry up to 150 seconds), and the group goes on from the exact post where it stood.
Can it read private groups?
Private groups are not supported: only public groups can be read without an account. A private group is skipped with a message in the log and nothing is charged for it.
A group is "not available on Facebook"?
Facebook shows the same page for a link, ID or name that does not exist, a group that was deleted, and a private group you cannot see. That group is skipped at once (not retried, nothing is charged for it), named in the log and in the run summary, and the other groups go on. If none of your groups can be read, the run ends with "No posts found" and their names (it is not marked as failed): check each link, ID or name (a private group cannot be read).
Why do I get fewer comments than commentsCount?
Facebook's count includes comments it hides from visitors (spam, removed, filtered by the group). All comments returns every comment Facebook shows publicly, in the order they were written. Replies go two levels deep: the replies to a comment, and the replies to those replies (depth 2, replies null: Facebook shows no deeper). One post's row is kept under 8 MB, the most a dataset item can hold: a post with so many comments and replies that it would pass that keeps the first ones and drops the last, you pay only for what is saved, and the log says how many posts were cut.
Where is an item for sale?
Tick Listing location (buy and sell groups): each item for sale gets listing.location with the city, the state, the place as the seller shows it (Nha Trang, Khánh Hòa), and the latitude and longitude. It is one extra page read per item, and it is charged only for the items whose location is found: an item whose page cannot be read is still saved, without a location and without the charge. The same item posted twice is read once, and charged with each post saved. Posts that are not for sale cost nothing more.
Is the data safe to open in Excel or to show on a web page?
Texts are the members' own words, copied as they are. A text can begin with -, +, = or @ (a phone number, a price such as -20%): Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. On a web page, escape every field like any text written by a stranger.
Known limitations
- Public groups only; a group's members list and Facebook's in-group search need a login (use
keywordsinstead). - Video links expire after a few days, like on Facebook: download the videos you need soon after the run.
onlyNewremembers post IDs, not their content: a post edited later, or whose reactions grew, is not returned again.- Two runs sharing the same
stateKeyat the same time may both return the same new post.
A run that reaches its timeout stops itself about 45 seconds before it: no new page is asked, what it read is saved and, with onlyNew, remembered, and the run ends Succeeded with "Stopped before the run's timeout". Resurrect it to go on from there, or give the next run a longer timeout (Run options).
A run the platform stops without warning (out of memory)
- Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the posts already saved are skipped: none is delivered or charged twice, and
maxItemsstill counts them. - With
onlyNew, the memory is saved after each write (at most once every 2 seconds): resurrect the stopped run and the posts it had saved meanwhile join the memory; leave it stopped for good, and the next run may return the posts of its last 2 seconds once more.
Something doesn't work?
The last line of the log counts the posts saved and filtered out, and the requests that failed after every retry. Those requests are listed, with the reason, in the FAILED_REQUESTS record of the run's key-value store. A run that saved nothing and had failed requests fails, and its last message gives the cause.
If Facebook changes its pages, you are told instead of paying for blank rows. If the first 20 posts read all lack their publication date, author, group name, reaction count or comment count, the run saves nothing more, stops and fails, and its last message names the missing field: at most those first posts are charged. A post that postedAfter / postedBefore drops because it has no date at all counts among those 20. A run of fewer posts (a scheduled onlyNew run that finds a few new ones, a small Max posts) is checked at its end, from 5 posts: its posts are already saved, and the run fails with the missing field instead of ending green.
🛟 Support
Open an issue in the Issues tab with a link to your run: the run log and the FAILED_REQUESTS record of the key-value store show exactly which requests failed and why.


