Facebook Page Post & Comment Scraper avatar

Facebook Page Post & Comment Scraper

Pricing

from $1.50 / 1,000 results

Go to Apify Store
Facebook Page Post & Comment Scraper

Facebook Page Post & Comment Scraper

⚡ High-Speed Facebook Page Scraper — 100+ Page URLs in One Run. Collect post text, media, timestamps, authors, engagement metrics, videos, reels, shared posts, and optional transcripts — no login or cookies required. Built for fast bulk scraping and automation.

Pricing

from $1.50 / 1,000 results

Rating

5.0

(2)

Developer

TheDoor

TheDoor

Maintained by Community

Actor stats

11

Bookmarked

1.4K

Total users

182

Monthly active users

6 hours ago

Last modified

Security

Limited permissions

Share

Facebook Page scraper for any public Page link: Page names, numeric ids, profile.php?id=, /p/, /pages/ and /people/ links, mobile links, and links to a Page's own posts. Paste the links, click Start, and get one row per post with the text, the time, the reactions, the comments count, the shares, the views, the photos and the videos.

Before you start: it reads a Page's feed, not one single post. A link to a post gives you the newest posts of that post's Page. Groups, reels, share links and private or login-only Pages are not supported.

Also included: reactions by type, up to 100 comments per post with their replies, video captions as text, date filters, only new posts on repeat runs so you don't pay twice for the same post, and a live status line on the run page.

💵 Follow a Page daily and save money: get only new posts

Run it every day and pay only for new posts. Turn on Only new posts for the next run and each run skips the posts you already have. Normal runs read the same posts again and charge you again.

Turn on Only new posts for the next run in the input form

Example: one Page with 5 new posts a day, checked daily for 30 days, Number of Posts at 100, Free planResultsCost with start fees
Normal runs3,000$7.80
With Only new posts245about $0.91

Set it up once:

  1. Paste the Page link and turn on Only new posts for the next run.
  2. Set Number of Posts higher than the new posts you expect between two runs.
  3. Click Save as a new task, then add a schedule. Daily suits most Pages; hourly suits a busy news Page.

More about only new posts

🔗 Works withPage names, numeric ids, profile.php?id=, /p/, /pages/, /people/, m. and web. links, and links to a Page's own posts
💯 Links per runNo fixed cap. Every Page in a run is read at the same time. Tested with 99 Pages in one run. A link that fails is skipped and the others keep going.
📄 OutputOne row per post, with its comments inside the same row
📊 DataText, time, reactions by type, comments, shares, views, photos, videos, shared links, top comment, video captions
♾️ How manyAs many posts as you ask for, up to what Facebook shows a logged-out visitor. Measured up to 1,000 posts from one Page.
⚡ SpeedUp to 2,000 posts a minute across many Pages: 1,771 posts from 45 Pages in 53 seconds at 4 GB memory. 240 posts from 4 Pages in 49 seconds at 1 GB. One big Page alone: 1,000 posts in about 8 to 9 minutes at 4 GB.
🔓 Account neededNone. No Facebook login or cookies. Public content only.
💰 Price$2.50 per 1,000 posts on the Free plan, down to $1.50 on Business. Apify's free $5 a month covers about 2,000 posts.

What you get: six posts from a run on 6 November 2026, showing the main columns.

Facebook posts as rows in the Output tab

Using an AI agent?
Actorthedoor/facebook-page-scraper
The one required fieldpageUrls, a list of links
Cap the billSet maxTotalChargeUsd on the run, for example 0.50
Why a link gave nothingRead the run's status message: it counts each kind of link that gave no posts
MCP linkhttps://mcp.apify.com/?tools=fetch-actor-details,thedoor/facebook-page-scraper

What you can do with it

  • Follow what competitors post, and which posts get the most reactions, comments and shares.
  • Watch brands, news Pages or public figures on a schedule and pay only for new posts.
  • Collect posts from a set date range for research or reports.
  • Turn video captions and comments into text for a spreadsheet, a sentiment tool or an AI workflow.

How to use it

  1. Paste your links into Facebook Page URLs, one per line.

  2. Set Number of Posts, the most posts to get from each Page. Start with 10 to see the data.

  3. Optional: add dates, comments or video captions.

  4. Click Start. The status line at the top of the run shows each step:

    Status lineWhat is happening
    Checking links: 3 of 10Each link is checked: is it a public Page?
    Reading posts: 2 of 5 Pages done, 340 results so farPosts are being collected. Results appear in the Output tab as they arrive.
    Done: 240 posts from 4 of 5 links. 1 link could not be opened (private, deleted, or not a Page). The Log tab lists them.The run is finished, with what it got and why any link gave nothing.
  5. Download the results as JSON, CSV or Excel.

Need every comment on one post? Copy its post.url into the Facebook Comment Scraper. For posts in public groups, use the Facebook Group Post Scraper.

How much does it cost?

You pay for each post in your dataset. Each post is one result. Apify's platform costs are included.

Apify planPrice per 1,000 posts
Free$2.50
Starter$1.99
Scale$1.70
Business and higher$1.50

Each run also has a start fee of $0.01 per GB of memory. Memory is set from the number of links: 1 GB for up to 39 links, 2 GB for 40 to 79, and 4 GB for 80 or more, so the fee is $0.01 to $0.04 unless you change the memory.

Comments, replies and video captions sit inside the post's row, so they add no results and cost nothing extra today.

You collect, on the Free planCost
50 posts from each of 10 Pages (500 posts)$1.25 + $0.01 start fee
40 posts from each of 45 Pages (at most 1,800 posts)at most $4.50 + $0.02 start fee
2,000 posts, the amount Apify's free $5 a month coversabout $5

Four ways to keep the bill under control:

  • Number of Posts: the most posts per Page. The most a run can give is postsToScrape x links.
  • Dates: postsNewerThan stops reading at your date, so old posts are never paid for.
  • Only new posts: see the next section.
  • Maximum cost per run: set it in the run options (maxTotalChargeUsd in the API). This is the most the run may charge you. Results already collected stay in your dataset.

More about only new posts

  • First run: posts as usual, up to Number of Posts.
  • Every next run: only posts published since your last run. Reading stops at your last post, so the run also ends sooner.
  • No new posts: 0 results and no result fee, only the small start fee. The status line says so.
  • A run fails partway: your place is kept, so the next run still picks up those posts.

When it is worth using:

  • Competitor watch: see each new post without paying for the old ones.
  • Brand or news monitoring: collect what a Page publishes, day by day.
  • A growing archive: add only the new rows to your sheet, with no duplicates to clean.
  • Daily AI summaries: send only today's posts to your AI workflow.

Good to know:

  • Turn it on from the first run. Runs with the option off do not save your place.
  • Keep Number of Posts high enough. You get the newest posts first. If a Page publishes 50 new posts and Number of Posts is 10, you get the newest 10, your place moves to the newest post, and the other 40 are not returned later.
  • Your place is saved per Apify account and per Page. Different links to the same Page share it.
  • Your place is saved when a Page finishes. If a run stops in the middle of a Page, the next run reads from the last saved place, so those posts come back and are charged again.
  • New comments on old posts are not returned. Old posts are not read again.
  • It works together with postsNewerThan. A post must pass both. It cannot be used with postsOlderThan.

What you give it

{
"pageUrls": [
"https://www.facebook.com/natgeo/",
"https://www.facebook.com/10643211755/"
],
"postsToScrape": 50,
"postsNewerThan": "7 days",
"includeTopComment": true
}
FieldDefaultWhat it does
pageUrlsrequiredFacebook links, always as a list, even for one link.
postsToScrape100The most posts to get from each Page.
postsNewerThanemptyOnly posts from a recent period or date: 30 minutes, 24 hours, 7 days, 3 months, or 2026-10-01.
postsOlderThanemptyOnly posts up to a date or age, in the same formats. A date includes that whole day in UTC. Use both for a date range.
onlyNewPostsoffOnly posts published since your last run on that Page. See the section above.
includeTopCommentonAdd the top comment of each post.
fetchAllCommentsoffAdd up to 100 top-level comments per post, in Facebook's "All comments" order. They replace the top comment.
fetchCommentRepliesoffAlso add the replies to those comments, at every level. Needs fetchAllComments. Runs take longer.
includeTranscriptoffAdd the video captions as text, when the video has them.

With postsOlderThan, Facebook usually starts the feed at your date. When it does not, the newer posts are loaded first to reach the date. Those posts are not returned, and they make the run longer.

Links it accepts: facebook.com/<name>, facebook.com/<number>, profile.php?id=<number>, /p/<name>-<number>/, /pages/<name>/<number>, /people/<name>/<number>, m. and web. versions, links with no https://, links with ?locale= or ?ref=, and links to a Page's tabs or posts such as /<name>/videos/ or /<name>/posts/<id>. Tabs and post links give you that Page's newest posts.

What you get back

One row per post. This is a real row from a run on 6 November 2026, with the commenter's details hidden and long links shortened:

{
"post": {
"id": "1704537707710319",
"type": "regular",
"url": "https://www.facebook.com/100044623170418/posts/1704537707710319",
"feedback_id": "ZmVlZGJhY2s6cGZiaWQwMnlHcXlNaHlX...",
"id_source": "post_id",
"text": "A tiny larval fish makes its way through the water atop a moon jelly.",
"hashtags": [],
"thumbnail": "https://scontent.ftij5-1.fna.fbcdn.net/v/t39..."
},
"page": {
"id": "100044623170418",
"name": "National Geographic",
"url": "https://www.facebook.com/natgeo/"
},
"created": {
"time": "Wed, 28 Oct 2026 22:00:00 GMT",
"timestamp": 1793224800
},
"engagement": {
"reactions": 1833,
"comments": 39,
"shares": 113,
"views": null,
"reaction_breakdown": { "like": 1532, "love": 240, "haha": 3, "wow": 48, "sad": null, "angry": null, "care": 10 }
},
"media": [
{
"id": "1704537664376990",
"url": "https://www.facebook.com/photo/?fbid=1704537664376990&set=a.528642321966536",
"__typename": "Photo",
"type": "Photo",
"media_type": "photo",
"uri": "https://scontent.ftij5-1.fna.fbcdn.net/v/t39...",
"thumbnail": "https://scontent.ftij5-1.fna.fbcdn.net/v/t39...",
"width": 526,
"height": 526
}
],
"video": { "is_video": false, "transcript": null, "music": null, "live_viewer_count": null },
"shared_content": null,
"comments": {
"top_comments": [
{
"id": "1832378061234409",
"feedback_id": "...",
"text": "The little fish is riding to get some COOKIES!",
"url": "https://www.facebook.com/natgeo/posts/pfbid0...",
"creation_timestamp": 1793345339,
"replies_count": 0,
"user": { "id": "...", "name": "...", "profileUrl": null, "profilePic": "..." },
"media": []
}
],
"top_comment_text": "The little fish is riding to get some COOKIES!"
},
"partnership": { "paid": false, "collaborators": [] },
"ads": { "page_ad_library": { "id": "23497828950", "is_business_page_active": false } },
"preview": {
"action_link": { "__typename": "MMEMessengerActionLink" },
"title": null,
"description": null,
"source": null,
"target": null
},
"references": { "text_references": [] },
"metadata": {
"page_index": 1,
"total_pages": 5,
"actors": [
{ "id": "100044623170418", "name": "National Geographic", "url": "https://www.facebook.com/natgeo", "type": "User" }
],
"user": { "id": "100044623170418", "name": "National Geographic", "url": "https://www.facebook.com/natgeo", "type": "User" }
}
}

What each field means:

FieldIn plain words
post.idThe post's unique number. Use it to spot the same post across runs.
post.typeregular for a normal post, reel for a reel.
post.urlA direct link to the post.
post.feedback_idFacebook's id for the post's reactions and comments. Useful only for technical work.
post.id_sourceWhere the post id came from. Useful only for technical work.
post.textWhat the Page wrote.
post.hashtagsThe hashtags in the text. [] means none.
post.thumbnailA picture for the post: the first photo, the video cover or the shared link's picture.
page.idThe Page's Facebook id.
page.nameThe Page's name.
page.urlThe link you pasted, so you can see which link the post came from.
created.timeWhen it was posted, as a readable date and time in UTC.
created.timestampThe same time as a number of seconds, handy for sorting in code.
engagement.reactionsAll reactions on the post added up.
engagement.commentsHow many comments the post has, as Facebook counts them.
engagement.sharesHow many times the post was shared.
engagement.viewsVideo views. null when Facebook shows no view count, as on most photo and text posts.
engagement.reaction_breakdownThe reactions split by type: like, love, haha, wow, sad, angry, care. null means Facebook showed no count for that type.
mediaEvery photo and video in the post. [] means none.
media[].idThe photo's or video's id.
media[].type, media[].media_type, media[].__typenameThe kind of item: photo or video, in Facebook's words and in lower case.
media[].url, media[].uri, media[].permalink_urlLinks to the item. For a photo, url opens it on Facebook and uri is the image file.
media[].thumbnailA picture of the item.
media[].width, media[].heightIts size in pixels.
media[].duration, media[].playable_duration_in_msA video's length, in seconds and in milliseconds.
media[].video_id, media[].videoIdThe same video id under two names.
media[].captions_url, media[].video_available_captions_localesLinks to the video's caption files and their languages.
media[].liveViewerCountPeople watching, for a live video.
media[].owner, media[].ocrTextThe video's owner, and text Facebook read from the image. Often empty.
video.is_videotrue when the post has a video or reel.
video.transcriptThe video captions as text, with includeTranscript on and when the video has them.
video.musicThe music on a reel, when Facebook shows it.
video.live_viewer_countPeople watching, for a live video.
shared_contentWhat the post shares. null means nothing is shared.
shared_content.linksEvery shared link or shared post, with its url, title and thumbnail.
shared_content.postThe shared Facebook post, with its shared_post_id.
shared_content.urlThe main outside link in the post.
comments.top_commentsThe comments, see below. [] means none.
comments.top_comment_textThe text of the first comment in the list.
partnership.paidtrue when Facebook marks the post as a paid partnership.
partnership.collaboratorsOther Pages or people credited on the post.
ads.page_ad_libraryThe Page's Ad Library id and whether its business account is active.
previewThe post's action button and link preview: action_link, title, description, source, target. null means none.
references.text_referencesPages, people and hashtags linked in the text, with where each one sits in the text (offset, length).
metadata.page_index, metadata.total_pagesThe link's place in your list, and how many links the run had.
metadata.actors, metadata.userWho posted it: everyone listed as an author, and the first of them.

comments.top_comments has two forms.

With includeTopComment only, it holds one comment with id, feedback_id, text, url, creation_timestamp, replies_count, media, and the author in user (id, name, profileUrl, profilePic).

With fetchAllComments, it holds up to 100 comments, and their replies if you asked for them, as one flat list:

FieldIn plain words
id, comment_url, post_urlThe comment's unique number, a direct link to it, and the post's link.
textWhat the person wrote.
comment_time, timestampWhen it was written, as a readable UTC time and as a number.
author_name, author_idThe name and Facebook id of the person or Page that wrote it.
author_profile_url, author_profile_pictureLinks to the author's profile and picture.
reactions_count, reaction_typesAll reactions, and the same reactions split by type. {} means none.
replies_countHow many direct replies the comment has.
is_reply, replyto_comment_id, depthfalse, null and 0 for a comment. A reply has true, the id of the comment it answers, and 1 or more.
image_url, mediaThe photo attached to the comment, and everything attached to it.
shared_link, shared_link_title, shared_link_source, shared_postA link or Facebook post shared in the comment.

Fields with no value come back as null, [] or an empty object. Counts are live and can change between runs.

When you get few or no results

The status line tells you how each link ended, and the Log tab names the Pages that failed. Links that give nothing add no rows to your dataset and no result fee.

What you seeWhat it meansWhat to do
1 link could not be opened (private, deleted, or not a Page)No public Page was found. The Page may be deleted, renamed, or limited by age or country, or the link is a group, reel or share link.Open the link in a private browser window. If you can see the Page there, run it again.
1 link is not a Facebook linkThe link is not on facebook.com.Fix the link.
1 Page had no posts to showThe Page is public and shows a logged-out visitor no posts.Nothing to fix.
1 Page had no posts in your datesNothing was published inside your dates.Widen the dates.
1 Page had no new posts since your last runWith onlyNewPosts, nothing new.Nothing to fix.
1 Page gave fewer posts because Facebook stopped showing moreFacebook stopped giving more posts partway. The posts read before that are kept.Run it again.
1 Page could not be readThe Page was found, but Facebook gave no posts.Run it again.
Stopped: ...The input has a problem, and the message says which. No Page was read.Fix the input and run again.
Fewer posts than you asked for, and none of the lines aboveThe Page has fewer posts, or fewer inside your dates.Nothing to fix.
One or two posts differ between two runsFacebook gives logged-out visitors a slightly different set each time. Two runs at the same moment differed by 3 to 4% in our tests.Nothing to fix.
No Done line, and the run shows Timed outIt reached the run timeout. Results read so far stay in your dataset.Raise the timeout and run again.

What it does not do

  • Pages, not single posts or groups. A post link gives you that Page's feed. For one post's comments use the Comment Scraper, and for groups use the Group Post Scraper.
  • No reel, photo, watch or share links. Use the Page's own link instead.
  • Public content only. Private, deleted, login-only, and age or country limited Pages give no posts, and the other links still run.
  • Personal profiles are not reliable. A public profile link can work, but the number of posts changes from run to run.
  • At most 100 top-level comments per post. For every comment on a post, use the Comment Scraper. There is no limit on replies per comment.
  • It does not remove duplicates between links. Two links to the same Page are read and charged twice.
  • It gives links to photos and videos, not the files.
  • A run has a time limit. The default is 1 hour. At the speed measured on one big Page, one hour reads about 6,600 to 7,800 posts. Raise the timeout for more. If the timeout is reached, the results collected so far stay in your dataset.
  • No email or phone numbers. Commenters' contact details are not returned.
  • It is not an official Facebook tool. theDoor is independent and is not affiliated with or endorsed by Facebook or Meta.

Questions people ask

Why did I get fewer posts than I asked for? The Page has fewer posts, fewer fall inside your dates, or Facebook stopped showing more to a logged-out visitor. The status line says which. See When you get few or no results.

Can I get posts from a date range? Yes. Set postsNewerThan to 2026-09-01 and postsOlderThan to 2026-09-30. Both days are included, in UTC.

Do comments count as results? No. They sit inside the post's row, so 3 posts with 23 comments are 3 results.

Can I run it every day? Yes. Save a task, add a schedule and turn on onlyNewPosts. See the section above.

Can I call it from code, Make, n8n or an AI agent? Yes. The API tab has Python, JavaScript and HTTP examples. In Python:

# pip install apify-client
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("thedoor/facebook-page-scraper").call(
run_input={
"pageUrls": ["https://www.facebook.com/natgeo/"],
"postsToScrape": 50,
},
max_total_charge_usd=0.50, # the most this run may spend
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row["created"]["time"], row["engagement"]["reactions"], (row["post"]["text"] or "")[:80])

Is it legal? It reads only public content. Posts, comments and author names can be personal data under GDPR and similar laws, so collect them only for a clear reason and keep only what you need.

Support

Open the Issues tab and paste the link you used and the run ID.