Facebook Posts Scraper avatar

Facebook Posts Scraper

Pricing

from $0.62 / 1,000 posts

Go to Apify Store
Facebook Posts Scraper

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

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

40

Total users

21

Monthly active users

2 hours ago

Last modified

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.

InputPage links or handles, up to 50 per run
OutputOne row per post: text, posting time, permalink, photos and videos, reactions by type, comments, shares, Page identity
Ceiling20 posts per Page, newest first
Account neededNone
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 getField
The post's id and permalinkpostId, postUrl
The full texttext, textLength
When it was postedtime, timestamp
Reactions, by type, plus comments and sharesreactionsCount, topReactions, commentsCount, sharesCount
What kind of post it ispostType, isReel, isSponsored
Every photo and video, with alt textmedia, mediaCount
The outbound link on a link postlinkUrl, linkTitle
The Page it came frompageName, pageId, pageUrl, pageIsVerified, pageFollowers, pageLikes, pageProfilePicture
The Page you asked forinputUrl

▶️ How to scrape Facebook posts

  1. Open Facebook Posts Scraper and click Try for free.
  2. Put your Pages into Facebook Page URLs, one per line.
  3. Set Posts per Page. Leave it at 20 unless you want fewer.
  4. Click Start.
  5. 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"
}
FieldDefaultWhat it is
startUrlsnonePage 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.
resultsLimitempty, runs as 20Posts per Page, newest first. 1 to 20, and 20 is all a public Page carries.
onlyPostsNewerThannoneDrop 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.
onlyPostsOlderThannoneThe other end of the window, same formats and the same refusal. Use both together to pull one month.
proxyUrlsnoneOptional. 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"
}
FieldHow to read it
postId, postUrlYour key, and the permalink. Reels come back as /reel/, videos as /videos/, ordinary posts as /posts/pfbid.
textThe full message as posted, not a preview. Line breaks and emoji are kept exactly.
time, timestampThe real posting time in ISO and in epoch seconds, read from the post rather than from a "2 days ago" label.
postTypevideo, photo, link or status.
mediaEach photo or video with an id, a permalink, a thumbnail, the alt text Facebook holds for screen readers, and durationMs on videos.
pageFollowers, pageLikesWhichever of the two Facebook publishes on that Page. The other comes back null, which is honest rather than missing.
sharesCountnull where the count is not published.

🧾 Reading the output

Three kinds of row can land in your dataset.

RowHow to spot itBilled
A postok: true and charged: trueyes
The sample row_sample: trueno
A diagnostic_diagnostic: true and an errorCodeno

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.

errorCodeWhat happened
BAD_INPUTThat 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_FOUNDNo public Page at that link.
NO_RESULTSThe Page came back but published no posts, or none inside your date window.
NOT_SERVEDThis post was not served this run. Re-run it later. Until 12 October 2026 this code was called BLOCKED.
NETWORKFacebook could not be reached.
TIME_BUDGETThe run ran out of time before reaching that Page.
PROXY_INPUT_ADJUSTEDA connection setting this actor does not use was dropped. The run carried on.
CHARGE_ERRORA billing event could not be recorded. Told to you rather than hidden.
UNEXPECTED_ERRORAnything 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 postId to 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:

  1. Run this on a Page with onlyPostsNewerThan set to 7 days.
  2. Sort on commentsCount and copy the postUrl of the top posts.
  3. 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 wantUse
Recent posts from a PageThis one
The comments under a post you have the link forFacebook Comments Scraper
Posts from a public groupFacebook Groups Scraper
Reels from a PageFacebook Reels Scraper
The ads a Page is runningMeta Ad Library Scraper
Recent posts from an Instagram accountInstagram 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.

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.