Request a tool
All toolsAutomationsGuidesMCP serverRequest a toolPlatformsCategories
Facebook Posts Scraper icon

Facebook Posts Scraper

Get recent public posts from any Facebook Page. Each post has text, post time, permalink, photos and videos. Plus reaction, comment and share counts.

6,668 runs on Apify $0.00065 per post ($0.65 / 1,000)
Run this in the cloudRun on Apify →

Developer & Research Tools

How it works

  1. 1
    Open it on Apify

    Hit Run on Apify — it opens the tool in the cloud, no install.

  2. 2
    Set the inputs

    Adjust startUrls, resultsLimit, onlyPostsNewerThan (sensible defaults are pre-filled).

  3. 3
    Click Run

    The tool runs on Apify’s cloud and collects the data for you.

  4. 4
    Export the results

    Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.

Pricing

$0.00065 per post = $0.65 per 1,000

You are charged forWhenPrice
Post scrapedCharged once per Facebook post returned. Sample rows and failure diagnostics are never charged.$0.00065

Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-08-16, and they are what you are actually charged.

Inputs

FieldWhat it doesType
startUrlsPublic Facebook Page URLs, one per line. A plain handle (NASA) or a profile.php?id= URL works too. Up to 50 Pages per run.array
resultsLimitHow many recent posts to return for each Page, newest first. The public Page render carries the 20 most recent posts, so 20 is both the default and the ceiling. Keep it low while you are testing - you pay per post.integer
onlyPostsNewerThanOptional. Drop posts older than this. Accepts a date (2026-08-01), a full timestamp, or a relative window such as "7 days". Filtered-out posts are never charged. It filters within the recent posts a Page exposes publicly - it does not reach further back in time. Anything that is not a date in one of those forms, such as "yesterday", stops the run before any Page is read, with nothing charged.string
onlyPostsOlderThanOptional. Drop posts newer than this. Same formats as above, and anything else is refused the same way. Filtered-out posts are never charged.string
proxyUrlsLeave this empty for a normal run. Fill it in only if you want the traffic to leave through proxy servers you already pay for, one URL per line, in the form http://user:pass@host:port.array
sessionCookiesLeave 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=…; xs=…". 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:

inputUrlpageNamepageIdpageUrlpageIsVerifiedpageFollowerspageLikespageProfilePicturepostIdpostUrltexttextLengthtimetimestamp

Export every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.

1 ready-to-run use cases

Facebook Page Posts - Newest First

Get the newest posts from any public Facebook Page: text, date, permalink, media and reaction counts. No login needed.

Related tools in Developer & Research Tools

Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.

GitHub Scraper iconDeveloper & Research Tools

GitHub Scraper

Search GitHub repos and users: stars, forks, language, topics, licence, plus user bio, company and followers. No token needed. $0.90 per 1,000 rows.

18 use cases

Stack Overflow / Stack Exchange Scraper iconDeveloper & Research Tools

Stack Overflow / Stack Exchange Scraper

Search Stack Overflow and Stack Exchange by keyword or tag. Score, answer count, views, reputation and body text. $2 per 1,000 questions.

2 use cases

Package Registry Scraper (npm + PyPI) iconDeveloper & Research Tools

Package Registry Scraper (npm + PyPI)

Get npm and PyPI package metadata as JSON. Version, license, author, repo, keywords and npm monthly downloads. $2 per 1,000 packages.

2 use cases

arXiv Scraper iconDeveloper & Research Tools

arXiv Scraper

Search arXiv papers by title, author, abstract or category. Get full abstracts, authors, categories, DOI, dates and PDF links. $2 per 1,000 papers.

2 use cases

OpenAlex Scholarly Works Scraper iconDeveloper & Research Tools

OpenAlex Scholarly Works Scraper

Search 250M+ OpenAlex papers with no API key. Get titles, authors, venue, year, citations, DOI, OA links and full abstracts. $2.00 per 1,000 papers.

2 use cases

Crossref Scholarly Works Scraper iconDeveloper & Research Tools

Crossref Scholarly Works Scraper

Search 150M+ papers on Crossref: DOI, title, authors, journal, publisher, date, citations and abstract. No API key. $1.00 per 1,000 works.

2 use cases

See all Developer & Research Tools →

Facebook Posts Scraper: recent public posts from any Page, with media and counts

Give it Page links or plain handles and you get their recent posts back, 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. The public version of a Page carries 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
Ceiling20 posts per Page, newest first
Account neededNone from you
Price$0.65 per 1,000 posts, flat on every plan

🔍 What Facebook Posts Scraper does

It reads the public version of the Page that Facebook publishes for search engines and lifts the posts out of the structured data already sitting inside it. One read per Page brings back the whole recent batch, so taking 20 posts from a Page costs the same time as taking 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 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.
resultsLimit20Posts per Page, newest first. 1 to 20, and 20 is all the 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.
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.
sessionCookiesnoneOptional, and most runs never touch it. Your own c_user and xs pair, so heavy runs use your account's own rate limit. Treat the values like a password.

Run it with empty input and you get one labelled sample row, free, so you can see the shape before you spend anything.

📤 What you get back

A real row from a real run. The post text is cut short, and the alt text and one link 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/lookaside/crawler/media/?media_id=1632778881550815",
      "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"
}
FieldWhat it is
inputUrlThe Page you asked for, so rows from several runs still group by Page.
postId, postUrlYour key, and the permalink. Reels come back as /reel/, videos as /videos/, ordinary posts as /posts/pfbid.
text, textLengthThe 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.
postType, isReel, isSponsoredvideo, photo, link or status, whether it is a reel, and whether it is a paid placement.
media, mediaCountEach photo or video with an id, a permalink, a thumbnail, the alt text Facebook holds for screen readers, and durationMs on videos.
linkUrl, linkTitleThe outbound link on a link post, null on everything else.
pageName, pageId, pageUrl, pageIsVerified, pageProfilePicturePage identity, repeated on each row so one row stands on its own.

pageFollowers and pageLikes are whichever of the two Facebook publishes on that Page. The other one comes back null, which is honest rather than missing. sharesCount is null 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.
BLOCKEDFacebook served a login screen for that Page instead of the timeline. Re-running usually clears it.
NETWORKFacebook could not be reached.
TIME_BUDGETThe run ran out of time before reaching that Page.
PROXY_INPUT_ADJUSTEDA proxyConfiguration 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.

▶️ How to run it

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.

💰 How much does it cost?

$0.65 per 1,000 posts. The same rate on every Apify plan, no volume tiers.

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 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.

🚧 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 it renders, 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.

🧭 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 Page, past the ten the tab showsFacebook Reels Scraper
The website, email and phone on a PageFacebook Page Contact Info Scraper

❓ Questions people ask

Do I need a Facebook account? No. Public Pages read fine without one. sessionCookies is there for people running heavily who would rather use their own account's rate limit.

Can I get more than 20 posts from one Page? Not from the 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.

Can I use a handle instead of a full link? Yes. NASA and https://www.facebook.com/NASA are the same input.

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.

Can I run it on a schedule? Yes, on Apify's scheduler, or start it from the API and read the dataset when it finishes.

🆘 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.