Facebook Posts Scraper
Pricing
from $0.62 / 1,000 posts
Facebook Posts Scraper
Scrape recent public posts from a public Facebook Page, no login needed. Each post has the full text, exact posting time and permalink, every photo and video, and reaction, comment and share counts, plus the Page identity. Up to 20 posts per Page, 50 Pages per run. $0.65 per 1,000 posts.
Pricing
from $0.62 / 1,000 posts
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
40
Total users
21
Monthly active users
2 hours ago
Last modified
Categories
Share
Give it Facebook Page links or plain handles and get their recent public posts, one row each: the full text, the exact posting time, the permalink, every photo and video, and the reaction, comment and share counts.
The ceiling is the thing to know first. A Page shows a signed-out visitor its 20 most recent posts, so 20 per Page is as deep as anyone reads it without logging in. This actor is built to go wide instead: 50 Pages in a run, newest posts from each, rather than a thousand posts from one Page.
| Input | Page links or handles, up to 50 per run |
| Output | One row per post: text, posting time, permalink, photos and videos, reactions by type, comments, shares, Page identity |
| Ceiling | 20 posts per Page, newest first |
| Account needed | None |
| Price | $0.65 per 1,000 posts on the free plan, down to $0.62 on Business. The free plan's $5 a month covers about 7,500 |
🔍 What Facebook Posts Scraper does
For every Page you list, it returns the newest posts that Page shows the public, one row per post. They come back together, so 20 posts from a Page take about as long as 3.
Reactions come back two ways. reactionsCount is the total, and topReactions breaks that same
total down by type, so you can see 3,356 likes against 3 angry without a second request.
The two date fields narrow that recent batch rather than reaching further back. On a Page that posts daily, asking for last quarter will correctly return nothing, and no post rows are charged.
📋 What data you get from each Facebook post
| What you get | Field |
|---|---|
| The post's id and permalink | postId, postUrl |
| The full text | text, textLength |
| When it was posted | time, timestamp |
| Reactions, by type, plus comments and shares | reactionsCount, topReactions, commentsCount, sharesCount |
| What kind of post it is | postType, isReel, isSponsored |
| Every photo and video, with alt text | media, mediaCount |
| The outbound link on a link post | linkUrl, linkTitle |
| The Page it came from | pageName, pageId, pageUrl, pageIsVerified, pageFollowers, pageLikes, pageProfilePicture |
| The Page you asked for | inputUrl |
▶️ How to scrape Facebook posts
- Open Facebook Posts Scraper and click Try for free.
- Put your Pages into Facebook Page URLs, one per line.
- Set Posts per Page. Leave it at 20 unless you want fewer.
- Click Start.
- Download the dataset as JSON, CSV or Excel, or pull it from the Apify API.
Run it with empty input and you get one labelled sample row, which is not charged, so you can see the shape before you spend anything.
💰 How much does it cost to scrape Facebook posts?
$0.65 per 1,000 posts. That is the free plan's price; paid plans pay a little less: $0.64 on Starter, $0.63 on Scale and $0.62 on Business. On the free plan, the $5 Apify gives you each month covers about 7,500 posts.
You pay for posts that come back with data. The sample row, every diagnostic row, posts dropped by your date filters and the same Page listed twice are not charged, and neither is a Page that turns out to have no public posts.
📥 What you give it
{"startUrls": ["https://www.facebook.com/NASA", "BBCNews"],"resultsLimit": 20,"onlyPostsNewerThan": "7 days"}
| Field | Default | What it is |
|---|---|---|
startUrls | none | Page links, one per line. A bare handle like NASA works, and so does a profile.php?id= link. First 50 per run, and the same Page written two ways is read once. |
resultsLimit | empty, runs as 20 | Posts per Page, newest first. 1 to 20, and 20 is all a public Page carries. |
onlyPostsNewerThan | none | Drop posts older than this. A date (2026-08-01), a full timestamp, or a window like 7 days. Dropped posts are never charged. Anything else, yesterday for one, stops the run before a Page is read and charges nothing for posts. |
onlyPostsOlderThan | none | The other end of the window, same formats and the same refusal. Use both together to pull one month. |
proxyUrls | none | Optional. One URL per line if you want the traffic to leave through servers you already pay for. |
📤 What you get back
A real row from a run on 21 September 2026. The post text is cut short, and the alt text and two links are trimmed:
{"ok": true,"charged": true,"recordType": "post","inputUrl": "https://www.facebook.com/NASA","pageName": "NASA - National Aeronautics and Space Administration","pageId": "100044561550831","pageUrl": "https://www.facebook.com/NASA/","pageIsVerified": true,"pageFollowers": 28726940,"pageLikes": null,"postId": "1632778914884145","postUrl": "https://www.facebook.com/NASA/posts/pfbid02ysmQKDUFAPT3a753WjmadF...","text": "No matter where you are, we all see the same Moon. ...","textLength": 247,"time": "2026-09-18T14:22:15.000Z","timestamp": 1789741335,"reactionsCount": 5542,"topReactions": [{ "type": "Like", "count": 3356 },{ "type": "Love", "count": 2013 },{ "type": "Care", "count": 127 },{ "type": "Haha", "count": 23 },{ "type": "Wow", "count": 20 },{ "type": "Angry", "count": 3 }],"commentsCount": 313,"sharesCount": 703,"postType": "photo","media": [{"type": "photo","id": "1632778881550815","url": "https://www.facebook.com/photo/?fbid=1632778881550815&set=a.416661013162614","thumbnailUrl": "https://lookaside.fbsbx.com/...","altText": "A view from low Earth orbit of Earth's horizon and a waxing gibbous moon. ...","style": "Photo"}],"mediaCount": 1,"isReel": false,"isSponsored": false,"linkUrl": null,"linkTitle": null,"scrapedAt": "2026-09-21T01:45:54.791Z"}
| Field | How to read it |
|---|---|
postId, postUrl | Your key, and the permalink. Reels come back as /reel/, videos as /videos/, ordinary posts as /posts/pfbid. |
text | The full message as posted, not a preview. Line breaks and emoji are kept exactly. |
time, timestamp | The real posting time in ISO and in epoch seconds, read from the post rather than from a "2 days ago" label. |
postType | video, photo, link or status. |
media | Each photo or video with an id, a permalink, a thumbnail, the alt text Facebook holds for screen readers, and durationMs on videos. |
pageFollowers, pageLikes | Whichever of the two Facebook publishes on that Page. The other comes back null, which is honest rather than missing. |
sharesCount | null where the count is not published. |
🧾 Reading the output
Three kinds of row can land in your dataset.
| Row | How to spot it | Billed |
|---|---|---|
| A post | ok: true and charged: true | yes |
| The sample row | _sample: true | no |
| A diagnostic | _diagnostic: true and an errorCode | no |
Filter on charged == true and you have your data. That flag is what separates real rows from the
sample and the diagnostics, not a receipt.
errorCode | What happened |
|---|---|
BAD_INPUT | That link could not be read as a Page, or a date field held something that is not a date. Group, event and watch paths land here too. |
NOT_FOUND | No public Page at that link. |
NO_RESULTS | The Page came back but published no posts, or none inside your date window. |
NOT_SERVED | This post was not served this run. Re-run it later. Until 12 October 2026 this code was called BLOCKED. |
NETWORK | Facebook could not be reached. |
TIME_BUDGET | The run ran out of time before reaching that Page. |
PROXY_INPUT_ADJUSTED | A connection setting this actor does not use was dropped. The run carried on. |
CHARGE_ERROR | A billing event could not be recorded. Told to you rather than hidden. |
UNEXPECTED_ERROR | Anything else, with the message attached. |
One quirk of the Console's Overview table: it shows the Page and post columns, so the engagement counts and the media look missing there. Open the row itself or download the JSON and they are all present.
💡 What people use it for
- Pulling twenty Pages every morning and diffing on
postIdto see only what is new. - Reporting: reaction, comment and share counts land as plain numbers, so engagement rate is a spreadsheet formula rather than a cleaning job.
- Deciding what to publish by reading what a whole category of Pages posted this week, sorted by
reactionsCount. - Keeping an archive of a Page you own, permalinks and media links included, so the record survives a deleted post.
From a Page's week to what people said about it, in three steps:
- Run this on a Page with
onlyPostsNewerThanset to7 days. - Sort on
commentsCountand copy thepostUrlof the top posts. - Paste them into Facebook Comments Scraper and read the comments themselves.
🚧 What it does not do
- No deep history. Twenty posts per Page is the ceiling, and the date filters work inside those twenty. If you need last year, this is the wrong tool.
- Public Pages only. Private timelines, groups, events and anything behind a login come back as an uncharged diagnostic row.
- Age-restricted and country-restricted Pages show a signed-out visitor no timeline at all. Those return an uncharged row, and re-running will not change it.
- No comment text and no reactor identities. You get the counts. The comments themselves are a separate actor, linked below.
- Pinned posts can be missing. Facebook leaves them out of the public timeline, so a Page whose newest content is pinned may show it lower down or not at all.
- Counts are a snapshot at read time and keep moving on a live post.
- Nothing is translated. The text comes back in the language it was written in.
- It is not an official Facebook tool. Dami's Studio is independent and is not affiliated with or endorsed by Facebook or Meta, or by any other company named on this page.
🧭 Which Facebook scraper do you need?
| If you want | Use |
|---|---|
| Recent posts from a Page | This one |
| The comments under a post you have the link for | Facebook Comments Scraper |
| Posts from a public group | Facebook Groups Scraper |
| Reels from a Page | Facebook Reels Scraper |
| The ads a Page is running | Meta Ad Library Scraper |
| Recent posts from an Instagram account | Instagram Scraper |
❓ Questions people ask
Do I need a Facebook account to scrape posts?
No. You need no Facebook account of your own for public Pages.
Can I get more than 20 posts from one Page?
Not from a public Page. That is what it carries, and nothing in the input raises it.
Why did a Page return nothing?
Either it publishes no posts, everything it has is outside your date window, or it is restricted to signed-in visitors. The diagnostic row says which.
Why do the numbers differ from what I see on Facebook?
Counts keep moving on a live post, and the row holds them as they were when it was read. If a post seems missing, open the Page in a private browser window: what a signed-out visitor sees there is what this actor reads.
Can I call it from code or connect it to an AI assistant?
Yes. The API tab has ready-made
code for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP client, connect
https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/facebook-posts-scraper. Either way the
run happens on your Apify account at the same price.
Is scraping Facebook legal?
This reads public Pages only, never private content. Results can still contain personal data, which GDPR and similar laws cover, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Paste the Page link you used and the run ID, and the log is enough for us to see what happened.
