Facebook Comments Scraper - Post and Reel Comments
Pricing
from $0.24 / 1,000 comments
Facebook Comments Scraper - Post and Reel Comments
Scrape comments from public Facebook posts, videos and reels. Paste the links; each row has the author, comment text, exact date, like count and reply count, with nested replies if you want them. No login needed. Up to 5,000 comments per post. $0.25 per 1,000 comments, less on paid plans.
Pricing
from $0.24 / 1,000 comments
Rating
5.0
(2)
Developer
Dami's Studio
Maintained by CommunityActor stats
2
Bookmarked
690
Total users
303
Monthly active users
3.9 hours
Issues response
3 days ago
Last modified
Categories
Share
Paste Facebook post, video or reel links and get the comments underneath them, one row per comment, with the author, the text, the exact time it was written, the like count and how many replies it drew.
The part worth knowing before you start: this reads posts, not Pages. A bare Page link like
facebook.com/natgeo comes back rejected, because a Page is not a post and has no single comment
thread. Reaction counts above roughly a thousand arrive rounded, because the rounded figure is the
only one Facebook publishes.
| Input | Post, video, reel, photo or group-post links, up to 100 per run |
| Output | One row per comment, plus one per reply if you ask for them: author, text, time, likes, reply count, attachments |
| Ceiling | 50,000 comments per post link |
| Speed | Roughly 3 to 4 comments a second, so 1,000 comments take 4 to 5 minutes |
| Account needed | None |
| Price | $0.25 per 1,000 comments on the free plan, down to $0.244 on Business. The free plan's $5 a month covers about 20,000 |
🔍 What Facebook Comments Scraper does
It opens the post the way a signed-out visitor sees it, then walks the comment thread to the end or to your limit, whichever comes first. Facebook hands comments out ten at a time and quietly ignores any request for a bigger page, so a hundred comments is ten round trips. That is the pace of the source, not a setting you can turn up.
Links in the permalink.php?story_fbid=...&id=... and story.php shapes are rewritten to the
equivalent /posts/ link before the run starts, so paste whichever form you have. A share link
(facebook.com/share/...) is followed to the post it opens.
Two URL fields come back on every row for that reason. inputUrl is your link exactly as you pasted
it, so you can join the results back onto your own list. facebookUrl is the canonical link
Facebook itself uses for that post, which is often a different pfbid string.
📋 What data you get from each Facebook comment
| What you get | Field |
|---|---|
| The comment's ids and link | commentId, id, feedbackId, commentUrl |
| What it says, and any photo, video or sticker | text, attachments |
| A link shared in the comment | sharedLinkUrl |
| Everything tagged in the comment with @ or #: people, Pages, groups and hashtags, with their links | tags |
| The tags Facebook marks as Pages, on their own | taggedPages |
| When it was written | date, timestamp |
| Likes, and replies under this comment | likesCount, likesCountText, commentsCount |
| Whether it is a reply, and to which comment | threadingDepth, replyToCommentId |
| On a reply, what that comment said and who wrote it | replyToCommentText, replyToProfileName |
| Who wrote it | profileName, profileId, profileUrl, profilePicture, author |
| The post it sits under, and its comment total | postId, postTitle, postDescription, pageName, facebookUrl, postCommentCount |
| The link you pasted | inputUrl |
▶️ How to scrape Facebook comments
- Open Facebook Comments Scraper and click Try for free.
- Paste your links into Facebook post URLs, one per line.
- Set Max comments per post. Start at 50 while you look at the shape of the output.
- 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 look at the shape before you spend anything.
💰 How much does it cost to scrape Facebook comments?
$0.25 per 1,000 comments. That is the free plan's price; paid plans pay a little less: $0.248 on Starter, $0.246 on Scale and $0.244 on Business. On the free plan, the $5 Apify gives you each month covers about 20,000 comments.
A reply costs the same as a top-level comment. You pay for comments that come back with data, so the sample row, every diagnostic row, comments dropped by your date filter and a comment repeated under the same link are not charged. Nor is a post that turns out to have no comments. If two different links lead to the same post, the post is read once per link and charged each time.
📥 What you give it
{"startUrls": [{ "url": "https://www.facebook.com/natgeo/posts/pfbid02rAK2eMyfVYDZbESKoNVuwWjcFr5BgRBfjp27nhgQToSiQD9NF3ypNdXpQuwSp7qnl" }],"resultsLimit": 50,"includeNestedComments": false}
| Field | Default | What it is |
|---|---|---|
startUrls | none | Public post, video, reel, photo or group-post links. First 100 per run, duplicates dropped. |
resultsLimit | empty, runs as 50 | Comments per post link, 1 to 50,000. Multiply by your number of links to get the ceiling on the run and on the spend. |
includeNestedComments | off | Also pull the replies under each comment. Each reply is its own row and counts towards the limit. |
maxRepliesPerComment | 60 | Only with replies on. The most replies read under any one comment, 1 to 1,000. They still count towards resultsLimit. |
viewOption | empty, runs as RANKED_UNFILTERED | How Facebook orders the thread before it is read: all comments (RANKED_UNFILTERED), most relevant (RANKED_THREADED), or newest first (RECENT_ACTIVITY). |
onlyCommentsNewerThan | none | Cut-off date. 2026-01-31, a full timestamp, a span like 3 days, 2 weeks ago, 24h or 7d, or yesterday / today. Older comments are dropped before they are billed. To fill the number you asked for, it reads on past older comments, up to four times that number of older ones a post (at least 100, at most 5,000). "Newest first" in Comments mode is quickest: it stops at the first older comment. A value it cannot read stops the run before anything is read, with a free BAD_INPUT row saying which forms work. |
proxyUrls | none | Optional. A list such as ["http://user:pass@host:port"], one entry per server, if you want the traffic to leave through servers you already pay for. Stored as a secret. |
📤 What you get back
A real row from a run on 21 September 2026. The post text and the comment text are both cut short here, and the links are trimmed:
{"ok": true,"charged": true,"recordType": "comment","inputUrl": "https://www.facebook.com/natgeo/posts/pfbid02rAK2eMyfVYDZbESKoNV...","facebookUrl": "https://www.facebook.com/natgeo/posts/pfbid0nMcunWuEpusFmY7mj...","postId": "1634927484671342","postTitle": "National Geographic","postDescription": "A punishing heat wave has left much of Europe in drought, causing rivers to run at record-low levels. ...","pageName": "National Geographic","commentUrl": "https://www.facebook.com/natgeo/posts/pfbid0nMcunWu...?comment_id=27860828630277533","commentId": "27860828630277533","date": "2026-08-15T06:07:03.000Z","timestamp": 1786774023,"text": "Perfect opportunity to clean our waters!!! Bring this history to the musuem for our kids. ...","likesCount": 107,"likesCountText": "107","commentsCount": 6,"threadingDepth": 0,"replyToCommentId": null,"profileName": "...","profileUrl": "https://www.facebook.com/...","attachments": [],"scrapedAt": "2026-09-21T01:45:48.038Z"}
| Field | How to read it |
|---|---|
commentId | The numeric comment id. Use it as your key. |
likesCount, likesCountText | Facebook publishes reactions as a display string ("28", "1.2K"). likesCountText keeps it, likesCount is that string as a number, so 1.2K reads as 1200. |
commentsCount | Replies under this comment, not the post's total. |
threadingDepth, replyToCommentId | 0 for a top-level comment, 1 for a reply, with the parent's id on the reply. A reply to a reply that Facebook shows inside that list comes back as 2, and replyToCommentId still names the top-level comment. |
replyToCommentText, replyToProfileName | Only on reply rows: the text and author of the comment replyToCommentId names. |
postCommentCount | The comment total Facebook gave for the post when the run read it, replies included, the same on every row of that post. null if Facebook gave none. |
sharedLinkUrl | The link a commenter shared, when Facebook attached a preview card for it. null otherwise, including a link typed into the text with no card. |
tags | Every tag in the comment, in order, each as {type, name, id, url}, with the name as written in the comment. type is profile, page, group or hashtag. Most Pages now run on Facebook's newer Page setup and arrive exactly like a person, so they come as profile too: a tagged Page is in this list, with its name and link. A profile's link is there when Facebook gives a numeric id, and null for the coded ids some people have. Empty when nothing is tagged. |
taggedPages | Only the tags Facebook still marks as Pages (older-style Pages), each as {name, id, url}. Usually empty: look for Pages in tags. |
profileId | A number on some accounts and an opaque pfbid string on others, and the pfbid form rotates over time. |
profileUrl | null for commenters whose profile Facebook renders without a public link. |
attachments | {type, url} for photo, video and sticker comments. Empty on ordinary text ones. |
🧾 Reading the output
Three kinds of row can land in your dataset.
| Row | How to spot it | Billed |
|---|---|---|
| A comment or a reply | ok: true and charged: true | yes |
| The sample row | _sample: true | no |
| A diagnostic | ok: false, _diagnostic: true and a code | 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.
code | What happened |
|---|---|
BAD_INPUT | That link is not a post link, or the date in "Only comments newer than" could not be read. The row says which part failed. |
NOT_FOUND | The post is private, deleted, or has no comment thread to read. |
NO_COMMENTS | The post is readable but has no comments, or none newer than your cut-off. |
DATE_FILTER_STOP | With a date filter, the post gave fewer new comments than you asked for before it reached the limit on older ones it reads. The row says how many it kept and skipped. Not charged. |
NOT_SERVED | This comment was not served this run. Re-run it later. Until 12 October 2026 this code was called BLOCKED. |
RATE_LIMITED | Facebook asked for a slower pace on that post. |
TARGET_ERROR | Facebook answered with something the run could not read. |
NETWORK | A request did not finish. |
DEAD_BATCH | Fifteen links in a row came back empty before anything had been delivered, so the run stopped instead of working through a list of dead links. The rest were not read and not charged. |
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. |
💡 What people use it for
- Reading what people actually said under a campaign post, instead of the reaction total.
- Watching a competitor's announcement thread for complaints and feature requests.
- Tracking a thread over days by re-running the same link and keying on
commentId.
From a Page to the conversation under its posts, in three steps:
- Run Facebook Posts Scraper on the Page
and copy the
postUrlof the posts you care about. - Paste them here, with
includeNestedCommentson. - Keep
threadingDepth0 for the top-level comments, and sort onlikesCountto see which ones people agreed with.
🚧 What it does not do
- Posts, not Pages. There is no Page-wide crawl here. Give it the links to the posts you care about, or use the Posts scraper above to find them first.
- Public content only. A private group, a friends-only post or a Page restricted by age or country comes back as an uncharged diagnostic row saying so.
- No reactions breakdown. You get the total, not how many were love, haha or angry. The public page does not carry it.
- No commenter email or phone. Not published, not inferable, not returned.
- Replies below the first level are not read. With replies on you get the replies under each comment, plus any reply to a reply that Facebook shows inside that list. The deeper threads behind them are not opened.
- Reply counts can exceed the rows you get. A comment may say six replies and return four when some were written by accounts that have since gone.
- 50,000 comments per link, inside the run's time limit. At 3 to 4 comments a second the default one-hour limit reads roughly 10,000 to 15,000 comments from one post, so raise the run's timeout before asking for more. Repeats Facebook sends are dropped rather than charged.
- A run that reaches its time limit stops cleanly. It keeps what it delivered and its status says what it did not finish.
- 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 |
|---|---|
| The comments under posts you already have links for | This one |
| Recent posts from a Page, with their links | Facebook Posts Scraper |
| Posts from a public group | Facebook Groups Scraper |
| Reels from a Page | Facebook Reels Scraper |
| The reviews and recommendations on a Page | Facebook Reviews Scraper |
| Comments under an Instagram post or reel | Instagram Comments Scraper |
| Comments under a YouTube video | YouTube Comments Scraper |
❓ Questions people ask
Do I need a Facebook account to scrape comments?
No. You need no Facebook account of your own for public posts.
Is the limit per post or per run?
Per post link. Ten links at 500 each is up to 5,000 rows, so keep an eye on it when you paste a long list.
Why did I get fewer comments than the post shows?
Either your cut-off date dropped them, or Facebook served fewer than the counter claims, which happens when commenters delete or deactivate. Open the post in a private browser window: the thread a signed-out visitor sees there is the one this actor reads.
Can I get replies to replies?
Only the ones Facebook shows inside a comment's reply list. They come back with threadingDepth 2
when includeNestedComments is on. The deeper threads behind them are not read.
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-comments-scraper.
Either way the run happens on your Apify account at the same price.
Is scraping Facebook comments legal?
This reads public posts only, never private content or messages. Comments, and the people tagged in them, are personal data, which GDPR and similar laws cover, so have a reason for collecting them and keep only what you need. 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 link you used and the run ID, and the log is enough for us to see what happened.