Facebook Engagement Scraper
Pricing
from $2.00 / 1,000 results
Facebook Engagement Scraper
Pricing
from $2.00 / 1,000 results
Rating
0.0
(0)
Developer
Andy Nguyen
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
3
Monthly active users
3 days ago
Last modified
Categories
Share
Facebook Post Engagement Scraper
An Apify Actor that extracts normalized engagement snapshots from direct public Facebook post URLs. It follows an HTTP-first strategy and retries incomplete or JavaScript-rendered pages with a controlled Playwright browser.
The Actor is intentionally scoped to direct posts. Page timelines, profile crawling, keyword search, private content, and comment pagination are outside the MVP.
Supported URLs
/{page}/posts/{id}and/{page}/posts/pfbid.../groups/{group}/posts/{id}for publicly visible group posts/reel/{id},/videos/{id}, and/watch/?v={id}/photo.php?fbid={id}story.phpandpermalink.phplegacy URLs/share/p/...,/share/v/...,/share/r/..., andfb.watchredirects
Page roots such as https://facebook.com/NASA are rejected because this Actor does not crawl timelines.
Input
{"startUrls": [{ "url": "https://www.facebook.com/NASA/posts/123456789" }],"includeReactionBreakdown": true,"maxConcurrency": 5,"proxyConfiguration": { "useApifyProxy": true }}
The Actor accepts up to 1,000 URLs. Tracking parameters are removed before run-wide deduplication. Facebook identity parameters such as story_fbid, fbid, id, and v are retained.
Output
Each unique submitted URL produces at most one dataset row. A failed URL does not terminate the rest of the batch.
{"postId": "123456789","code": "pfbidExample","url": "https://www.facebook.com/NASA/posts/pfbidExample","originalUrl": "https://m.facebook.com/share/p/example/","postType": "video","text": "A new view of the cosmos #NASA","sharedUrl": "https://example.com/article","createdAt": "2026-09-05T12:34:56.000Z","reactionCount": 1200,"reactionBreakdown": {"like": 900,"love": 200,"wow": 100},"commentCount": 80,"shareCount": 20,"viewCount": 15000,"engagementCount": 1300,"author": {"id": "42","username": "NASA","name": "NASA","isVerified": true,"profileUrl": "https://www.facebook.com/NASA","profilePicUrl": "https://scontent...jpg","type": "page"},"media": [],"hashtags": ["NASA"],"mentions": [],"status": "success","missingFields": [],"error": null,"scrapedAt": "2026-09-06T14:20:10.000Z"}
Facebook does not expose equivalents for Threads quoteCount and isReply, so they are intentionally absent. Facebook fields use their native semantics:
reactionCountinstead of ThreadslikeCountcommentCountinstead of ThreadsreplyCountshareCountinstead of ThreadsrepostCountengagementCount = reactionCount + commentCount + shareCount
sharedUrl is the external destination linked by the post. It is extracted from the post text, GraphQL attachment data, or the rendered link preview; Facebook link-shim URLs such as l.facebook.com/l.php, mobile variants, warning pages, and legacy redirects are unwrapped. It remains null when the post has no external destination.
Unavailable counts are null, never fabricated as zero. A row is partial when postId or a core engagement count is unavailable and missingFields lists those fields.
Extraction strategy
- Validate, normalize, and deduplicate input URLs.
- Fetch public HTML with CheerioCrawler.
- Parse embedded structured payloads, Open Graph metadata, and engagement objects.
- Send incomplete pages to PlaywrightCrawler.
- Merge browser and HTTP results without replacing known values with
null. - Emit
success,partial,not_found,private,blocked, orfailedrows.
sharedThumbnailUrl preserves an explicit preview when available, then falls back to the first extracted media preview or image URL (including Open Graph media). Video stream URLs are never used as inferred thumbnails. Generic Story/Post types use media to distinguish photos and videos; explicit reel and link types are preserved.
Only public, logged-out Facebook content is in scope. Use this Actor in compliance with Facebook's terms and applicable privacy and data-protection laws.
Development
npm installnpm run check
Local Actor input belongs in storage/key_value_stores/default/INPUT.json, then run:
npm run buildnpm start