Facebook Groups Scraper
Scrape public Facebook group posts without logging in: author, text, time, permalink, media and engagement counts.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
startUrls,resultsLimit,viewOption(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Inputs
| Field | What it does | Type |
|---|---|---|
startUrls | Public Facebook group URLs, e.g. https://www.facebook.com/groups/dogspotting/. Numeric group URLs work too. Up to 20 groups per run. | array |
resultsLimit | How many posts to return in total across all groups. Maximum 1000. Only real posts are charged. | integer |
viewOption | Which feed ordering Facebook should return: new posts, newest activity, or most relevant. | string |
onlyPostsNewerThan | Keep only posts created after this point. YYYY-MM-DD, a full ISO timestamp, or a relative value like "7 days". Filtered-out posts are never charged. | string |
onlyPostsOlderThan | Keep only posts created before this point. Same formats as above. | string |
proxyUrls | Advanced and almost never needed. Leave this empty and the Actor uses its own built-in egress, which costs you nothing extra and is already tuned for this target. If you do fill it in, these are YOUR servers on YOUR bill, one URL per line, e.g. http://user:pass@host:port. | array |
sessionCookies | Leave this empty unless you need it. Runs are logged out by default and that is enough for public Facebook content. Facebook shows some things only to a signed-in account, and it limits how fast any one account may read; supplying your own cookie uses your account and your own rate limit, shared with nobody. In Chrome: open facebook.com while signed in, press F12, then Application > Cookies > https://www.facebook.com, and paste the values as "c_user=<value>; xs=<value>". One line per account. Treat these like a password: anyone with them can act as that account, and Facebook may sign the session out or restrict the account for automated use. | array |
What you get
A structured dataset — each result includes fields like:
groupTitleusertexttimelikesCountcommentsCountsharesCountattachmentsCounturlfacebookUrlidExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
Related tools in Social Media Scrapers
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
Facebook Posts Scraper
Scrape posts from any public Facebook Page: text, time, permalink, media, reactions, comments and shares. No login, no cookies. $0.60 per 1,000 posts.
Facebook Reels Scraper
Scrape public Facebook Page Reels - up to 200 per Page: views, reactions, comments, shares, captions, hashtags, duration, MP4 and thumbnail links. No login.
Instagram Post Scraper
Scrape Instagram posts and reels by link or shortcode for $0.18 per 1,000, flat at every volume.
Instagram Post Scraper
Scrape Instagram posts and reels with no login: caption, like and comment counts, publish date, every carousel image and video URL, owner and hashtags.
Instagram Profile Scraper
Bulk Instagram profile scraper. Usernames or profile URLs in, one row out: bio, exact follower, following and post counts, verified flag, category, e-mail.
Instagram Profile Scraper
Scrape Instagram profiles by username: bio, followers, following, posts count, verified flag, business category, bio links and HD avatar. No login.
Where this tool sits
- Categories
- Social Media Scrapers
Facebook Groups Scraper — public group posts, no login
Paste public Facebook group URLs, get their posts back as structured rows: author name and profile picture, post text, timestamp, permalink, attached photos and videos, and reaction, comment and share counts.
No Facebook account. No cookies to paste. No session token, no browser, no captcha solving. You give it a group URL, it gives you rows.
Price
$0.70 per 1,000 posts — $0.0007 per post — plus a $0.002 start fee per run.
That is the cheapest Facebook group post scraper on the market, and the rate is flat: the same $0.70 on the free plan as on any paid plan, no volume tiers, no minimum spend, no monthly rental.
You are charged once per post row that actually lands in the dataset. Nothing else bills:
- the free sample row you get from an empty run — free
- diagnostic rows (private group, bad URL, throttled, no posts in your date range) — free
- posts dropped by your
onlyPostsNewerThan/onlyPostsOlderThanfilter — free - proxy bandwidth — free, there is no per-gigabyte surcharge on this Actor at all
The start fee is billed per gigabyte of run memory. The default is 1 GB, so it is charged once.
| Posts returned | What you pay |
|---|---|
| 0 (group turned out private) | $0.002 |
| 20 | $0.016 |
| 100 | $0.072 |
| 500 | $0.352 |
| 1,000 | $0.702 |
Input
| Field | Type | What it does |
|---|---|---|
startUrls | array | Public Facebook group URLs. Vanity URLs (/groups/dogspotting/) and numeric URLs (/groups/874728723021553) both work. Up to 20 groups per run. |
resultsLimit | integer | Total posts across all groups. Maximum 1000. Default 20. |
viewOption | string | CHRONOLOGICAL (new posts), RECENT_ACTIVITY (newest activity), TOP_POSTS (most relevant). |
onlyPostsNewerThan | string | Keep posts after this point. 2026-01-01, a full ISO timestamp, or a relative value like 7 days. |
onlyPostsOlderThan | string | Keep posts before this point. Same formats. |
proxyUrls | array | Optional, and almost nobody needs it. Your own proxy servers, on your own bill. Leave it empty and the Actor uses its own egress at no extra cost to you. |
Field names follow the naming convention that is common across Facebook scrapers, so an input you already have usually pastes straight in and a downstream pipeline usually needs no rewriting.
{
"startUrls": [
{ "url": "https://www.facebook.com/groups/dogspotting/" }
],
"resultsLimit": 100,
"viewOption": "CHRONOLOGICAL",
"onlyPostsNewerThan": "30 days"
}
Run it with no input at all and you get one clearly labelled sample row, uncharged, so you can see the exact output shape before spending anything.
Output
One row per post. This is a real row, trimmed only where the image URLs would run off the page:
{
"ok": true,
"recordType": "post",
"charged": true,
"facebookUrl": "https://www.facebook.com/groups/dogspotting/",
"url": "https://www.facebook.com/groups/dogspotting/permalink/10166019288919467/",
"id": "10166019288919467",
"legacyId": null,
"time": "2026-08-15T12:30:13.000Z",
"timestamp": 1786797013,
"text": "A beauty 🫶",
"user": {
"id": "pfbid0gf27iWyWWmzm8KJaTYpsWb93g5SVDn5KDmaxFTmxDYWsLH1hdCC4tYJDe5tGQFXVl",
"name": "Daniela Lisa Lombardi",
"profileUrl": null,
"profilePic": "https://scontent.xx.fbcdn.net/v/t1.6435-1/758252895_...jpg"
},
"likesCount": 35,
"commentsCount": 1,
"sharesCount": 0,
"topReactionsCount": [18, 16, 1],
"attachments": [
{ "type": "photo", "thumbnail": "https://scontent.xx.fbcdn.net/v/t39.30808-6/774136759_...jpg", "id": "10165027268481605" }
],
"attachmentsCount": 4,
"isVideo": false,
"link": null,
"groupId": "10487409466",
"groupTitle": "Dogspotting",
"inputUrl": "https://www.facebook.com/groups/dogspotting/",
"scrapedAt": "2026-08-15T13:29:20.412Z"
}
Field reference
| Field | Meaning |
|---|---|
id | Facebook's post id. Stable, safe to use as a primary key. |
url | Direct permalink to the post. |
facebookUrl | The group the post belongs to. |
time / timestamp | Creation time as an ISO 8601 string and as Unix seconds. Always the same instant. |
text | The post body. null for posts that are only a photo or a video. |
user.name | Author display name as Facebook renders it publicly. |
user.id | The author's opaque profile id (a pfbid… string). It rotates over time — do not treat it as a permanent identity. |
user.profilePic | Avatar URL. These are signed CDN links and expire in a few days. Re-host anything you need to keep. |
user.profileUrl | Usually null on group feeds. Facebook does not put the author's profile link in the group feed payload. |
likesCount | Total reactions, all types combined. |
commentsCount | Comment count as shown on the post. |
sharesCount | Share count. Frequently 0 for group posts, because group posts are usually not shareable. |
topReactionsCount | Counts of the individual top reaction types, most-used first. |
attachments | Photos and videos, de-duplicated. Videos carry videoUrl where the payload exposes one. |
isVideo | True when at least one attachment is a video. |
link | External link attached to the post, with its title and description when Facebook rendered a preview card. |
groupId / groupTitle | Numeric group id and group name, resolved from the handle you supplied. |
recordType | post for real data, sample for the free example row, diagnostic for a free explanation of something that went wrong. |
charged | Whether that specific row was billed. Only post rows are ever true. |
Diagnostic rows carry ok: false and a code — NO_PUBLIC_POSTS, BAD_INPUT, RATE_LIMITED, BLOCKED, SCHEMA_DRIFT, NO_RESULTS, STOPPED_EARLY — with a details sentence explaining what happened. To keep only real posts, filter on recordType === "post".
What it does not do
Written plainly, because finding this out after you have paid is worse than reading it here.
- Public groups only. A private or closed group shows its feed to members and nobody else.
There is no scraping trick that changes that — the data is simply not served to a logged-out visitor. Point this Actor at a private group and you get one free diagnostic row saying so, and a bill of exactly the start fee.
- No comments. It returns the comment *count*, not the comment text. This Actor scrapes the
group feed, not individual post threads.
- No member lists. Group membership is not public.
user.profileUrlis usually null, andlegacyIdis usually null. Those fields exist because
the feed payload sometimes carries them; most of the time it does not. They are never invented.
- 1,000 posts per run. Deep pagination gets slower and more likely to be throttled the further
back you go. If you need more, run again with a date filter or split the groups across runs.
- Throttling is real. Facebook meters this endpoint per outgoing address, not per account. A
run that hits a throttled window returns free diagnostic rows instead of posts, succeeds rather than failing, and bills only the start fee. Waiting a few minutes and re-running is normally enough; heavy back-to-back runs against the same group are what triggers it.
- A run that returns nothing stops early on purpose. If the first few groups in your list give
back no posts — all private, all throttled, all mistyped — the run stops rather than walking the remaining URLs, and writes a STOPPED_EARLY or RATE_LIMITED row naming the ones it skipped. That keeps a run that was never going to return data down to a single start fee. Fix or drop the dead URLs and run again.
sharesCountis often 0. That is what Facebook reports for most group posts, not a parsing
bug.
- Media URLs expire. Every
scontent.*.fbcdn.netlink is signed and short-lived. Download what
you want to keep, promptly.
- No login, ever. It does not accept a session cookie, it does not want your credentials, and
it will not scrape anything that requires being logged in. That is a deliberate design choice: an account-based scraper gets the account banned, and the ban lands on whoever supplied it.
How it works
The group page is fetched as an ordinary logged-out visitor. Facebook usually answers that with its "you must log in to continue" shell, which looks like a dead end and is not: the shell carries the CSRF token and build identifiers that the site's own JavaScript would use, and the site's public feed endpoint accepts them. The Actor then calls that endpoint the same way the page would, reads the streamed response, and turns each story into a row.
Two consequences worth knowing about. First, there is no headless browser anywhere in this Actor, which is most of the reason it can be priced where it is — starting a headless browser costs many times more per run than an HTTP request does. Second, when Facebook changes the shape of that query, the Actor re-reads the current identifiers from Facebook's own public script bundles and retries once before giving up, so a routine site change does not need a redeploy to recover.
FAQ
Do I need a Facebook account, cookies, or an access token? No. Nothing to log into, nothing to paste, nothing to keep alive. If you have used scrapers that ask you for a session cookie, this is not one of them.
Can it scrape private or closed groups? No, and neither can anything else without an account inside the group. You get a free diagnostic row explaining it rather than a silent empty result.
How much does it cost to scrape 1,000 posts? $0.702 — a $0.002 start fee plus 1,000 × $0.0007. There is no subscription and no minimum.
What happens if the group is empty, private, or the URL is wrong? The run succeeds, writes a free diagnostic row saying which of those it was, and charges you the start fee only. It never fails the run to tell you a URL was wrong, because a failed run still bills a start fee and you should not pay extra for a typo.
Does it get comments too? No. Comment counts only. This scrapes the group feed.
Can I filter by date? Yes — onlyPostsNewerThan and onlyPostsOlderThan accept 2026-01-01, a full ISO timestamp, or a relative value such as 7 days or 3 months. Posts you filter out are not charged.
Can I scrape several groups in one run? Up to 20. resultsLimit is the total across all of them, split evenly, and any share a group cannot fill — because it is private or ran out of posts — is handed to the groups that can.
How do I sort by newest? viewOption: "CHRONOLOGICAL". That is the default.
Why is sharesCount zero on most posts? Because Facebook reports zero. Most group posts are not shareable outside the group.
Do the image URLs stay valid? No. They are signed CDN links that expire within days. Download anything you intend to keep.
Can I use my own proxies? Yes, put them in proxyUrls. You almost certainly do not need to — the built-in egress is already tuned for this target and carries no bandwidth surcharge either way.
Is this legal? It reads pages that are published to the open internet with no login. What you then do with personal data — names, profile pictures, post text — is your responsibility, and in the EU and UK that means GDPR applies to you as the controller. Scrape public groups, respect deletion requests, and do not use it to build a spam list.
Integration
Runs like any other Actor: from the Console, from the API, from the JavaScript or Python client, from a schedule, or over MCP from an AI assistant. Results land in the default dataset and export as JSON, CSV, Excel, XML or RSS.
curl -X POST "https://api.apify.com/v2/acts/dami_studio~facebook-groups-scraper/runs?token=YOUR_TOKEN" \
-H 'content-type: application/json' \
-d '{"startUrls":[{"url":"https://www.facebook.com/groups/dogspotting/"}],"resultsLimit":100}'
Support
If a group returns a diagnostic row you think is wrong, open an issue on the Actor with the group URL and the run id. Schema changes on Facebook's side are the usual cause and they get fixed quickly.