Facebook Posts Scraper โ€” Engagement Analytics Report avatar

Facebook Posts Scraper โ€” Engagement Analytics Report

Pricing

$19.99/month + usage

Go to Apify Store
Facebook Posts Scraper โ€” Engagement Analytics Report

Facebook Posts Scraper โ€” Engagement Analytics Report

๐Ÿ“˜ Facebook Posts Scraper โ€” Engagement Analytics Report extracts public posts, reactions, comments, timestamps, media & links from pages/groups at scale. โš™๏ธ Export JSON/CSV, API-ready. ๐Ÿ”Ž Perfect for social listening, competitor analysis & content researchโ€”privacy-safe and TOS-compliant. ๐Ÿš€

Pricing

$19.99/month + usage

Rating

0.0

(0)

Developer

Scrapium

Scrapium

Maintained by Community

Actor stats

0

Bookmarked

27

Total users

8

Monthly active users

10 days ago

Last modified

Share

Facebook Posts Scraper โ€” Engagement Score & Reaction Analytics

Facebook Posts Scraper โ€” Engagement Analytics Report pulls a public Facebook Page's recent posts and scores every one for engagement: a weighted engagementScore, an engagementRate normalized against that page's own average, the dominantReaction, and a full reactionMixPct breakdown โ€” plus one run-level summary row per page with average engagement, best posting hour, and posting cadence. Every response comes back as structured JSON, ready to pass directly to an LLM, index into a vector store, or feed a monitoring pipeline. Point it at a page and start comparing posts today.

What is Facebook Posts Scraper โ€” Engagement Analytics Report?

Facebook Posts Scraper โ€” Engagement Analytics Report is an Apify Actor that reads a public Facebook Page's timeline over HTTP and layers computed engagement metrics on top of every post it returns, entirely in Python and without any extra network requests. No Facebook account, login, or cookie is required โ€” the input schema has no credential field at all, and the Actor reads the same public timeline a logged-out visitor sees. Give it one or more page URLs or usernames and it scores each post against that page's own posting history.

  • Per-post engagement scoring โ€” engagementScore (likes + 2ร—comments + 3ร—shares), engagementRate (score รท that page's own average for the run), dominantReaction, and reactionMixPct
  • Page-level summary row โ€” one rowType: "summary" row per page with avgEngagement, avgReactions, avgComments, avgShares, bestPostingHour, postingCadenceDays, and topPostUrl
  • Minimum-engagement filter โ€” drop posts below an engagementScore threshold before they're emitted or averaged
  • Optional video/reel transcripts โ€” extract caption text into captionText when Facebook serves one
  • Date-window filtering โ€” restrict the sample to posts after and/or before a given absolute or relative date
  • Auto or manual per-page timeout โ€” the run's time budget scales automatically with sample size, or you can set it yourself

What data can you get with Facebook Posts Scraper โ€” Engagement Analytics Report?

Every run returns two row types in the same dataset โ€” scored posts and, optionally, one summary row per page.

Result TypeExtracted FieldsPrimary Use Case
Scored postpostId, pageName, text, time, timestamp, url, topLevelUrl, likes, comments, shares, topReactionsCount, reactionLikeCount, reactionLoveCount, reactionHahaCount, reactionCareCount, reactionSadCount, reactionWowCount, reactionAngryCount, engagementScore, engagementRate, dominantReaction, reactionMixPct, user, collaborators, media, captionText, feedbackId, facebookId, facebookUrl, pageAdLibrary, inputUrlPer-post engagement analysis, top-post identification
Page summarypageName, postsAnalyzed, avgEngagement, avgReactions, avgComments, avgShares, bestPostingHour, postingCadenceDays, topPostUrl, facebookUrl, inputUrlPage-level benchmarking, posting-schedule planning

Engagement score and reaction mix

Every scored post carries four computed fields, not just raw counts. engagementScore weights shares and comments above plain likes (likes + 2ร—comments + 3ร—shares) so a highly-shared post outranks a post with the same like count but no shares. engagementRate then divides that score by the average engagementScore of the posts kept for that page in this run โ€” 1.0 means exactly average, 2.0 means double โ€” so you can tell an over- or under-performing post apart from the page's baseline without a second lookup. dominantReaction names the largest of the seven reaction buckets, and reactionMixPct turns all seven into a percentage breakdown. Both are null when a post has zero reactions โ€” the Actor never invents a value for missing signals.

{
"engagementScore": 6288,
"engagementRate": 1.7212,
"dominantReaction": "like",
"reactionMixPct": { "like": 77.13, "love": 5.22, "haha": 2.19, "care": 1.09, "sad": 10.0, "wow": 2.39, "angry": 1.99 }
}

Page summary row

When includeSummary is on (the default), each page gets one extra rowType: "summary" row after its post rows: avgEngagement, avgReactions, avgComments, and avgShares (means over the posts kept after the minEngagement filter), bestPostingHour (the UTC hour that shows up most often across the sample), postingCadenceDays (the mean gap in days between consecutive posts), and topPostUrl (the single highest-engagementScore post). It's the fastest way to get a page's baseline without averaging the post rows yourself.

How does Facebook Posts Scraper โ€” Engagement Analytics Report differ from the official Facebook API?

Meta's Graph API can read a Page's own feed with a Page Admin access token, or another Page's public feed only through the Page Public Content Access feature, which requires Meta App Review and business verification (per Meta's Graph API documentation for Page Public Content Access, checked 2026-07-26). Facebook Posts Scraper โ€” Engagement Analytics Report reads the same publicly visible feed for any page or handle without that approval process.

FeatureFacebook Graph APIFacebook Posts Scraper โ€” Engagement Analytics Report
Access to a page you don't manageOnly via Page Public Content Access, requiring Meta App Review + business verificationAny public page URL or handle, no approval
Per-type reaction breakdownRequires a Page access token you administerComputed for any public page from the visible feedback payload
Computed engagement scoringNot provided โ€” raw counts only, scoring is left to youengagementScore and engagementRate computed automatically every run
Page-level aggregatesNot provided by the API itselfOne summary row per page with average engagement, best hour, and cadence
SetupRegister a Meta app, request permissions, complete App ReviewAdd a page URL or username and run

Use the Graph API when you manage the page and need first-party Insights data like reach or impressions. Use Facebook Posts Scraper โ€” Engagement Analytics Report when you need computed engagement scoring for pages you don't manage โ€” including competitors โ€” without app review.

How to scrape Facebook with Facebook Posts Scraper โ€” Engagement Analytics Report?

  1. Open Facebook Posts Scraper โ€” Engagement Analytics Report on the Apify platform.
  2. Add one or more Facebook Page URLs or usernames to pageUrls โ€” nothing is required by the schema, but at least one target is needed to get results.
  3. Set postsPerPage (sample size), minEngagement (score threshold), and optionally postsFrom/postsUntil to bound the date window.
  4. Start the run โ€” no proxy setup needed; the Actor prefers Apify's residential proxy and falls back to datacenter automatically.
  5. Download or stream results as JSON or CSV from the run's dataset.

Example input for two pages, newest posts first, capped at 50 each:

{
"pageUrls": ["nytimes", "https://www.facebook.com/Cristiano/"],
"postsPerPage": 50,
"minEngagement": 0,
"includeSummary": true
}

How to run multiple queries in one job

pageUrls accepts an array, so a single run can score several pages at once. Each page is scraped and scored independently โ€” its engagementRate is normalized against its own average, not a cross-page average, and it gets its own summary row when includeSummary is on. The Actor processes each target sequentially, one page at a time (with a short pause between targets); it does not document a configurable concurrency setting for page-level parallelism.

โฌ‡๏ธ Input

Facebook Posts Scraper โ€” Engagement Analytics Report takes one or more Facebook Page targets plus optional sample-size, scoring, date-window, and timeout controls. Nothing is required by the schema.

ParameterRequiredTypeDescriptionExample Value
pageUrlsNoarrayOne or more Facebook page targets to analyze โ€” full URLs or bare usernames. Each page is scored independently.["nytimes", "https://www.facebook.com/Cristiano/"]
postsPerPageNointegerHow many recent posts to pull and score per page (default 10, minimum 1, maximum 1,000,000).50
minEngagementNointegerDrop posts whose engagementScore is below this value before they're emitted or averaged (default 0).0
includeSummaryNobooleanEmit one extra rowType: "summary" row per page with the page's averages, best hour, and cadence (default true).true
fetchVideoTranscriptsNobooleanExtract closed-caption/transcript text from video and reel posts into captionText (default false).false
postsFromNostringLimit the sample to posts after this date โ€” absolute (2024-01-01) or relative (7 days, 2 months). Empty means no lower bound."7 days"
postsUntilNostringLimit the sample to posts before this date โ€” absolute or relative (0 for today). Empty means no upper bound.""
timeoutModeNostringauto (default, scales the time budget from sample size) or manual (uses targetTimeoutSecs)."auto"
targetTimeoutSecsNointegerPer-page timeout in seconds, used only when timeoutMode is manual (default 1200, minimum 60, maximum 72000).1200
proxyConfigurationNoobjectApify Residential proxy is preferred, with automatic Datacenter fallback. Custom proxy URLs are also accepted.{"useApifyProxy": true}

Example JSON input:

{
"pageUrls": ["nytimes", "https://www.facebook.com/Cristiano/"],
"postsPerPage": 50,
"minEngagement": 0,
"includeSummary": true,
"fetchVideoTranscripts": false,
"postsFrom": "30 days",
"postsUntil": "",
"timeoutMode": "auto"
}

Common pitfall: minEngagement filters posts out before engagementRate is computed, and the page average used for that computation is taken only over the posts that survive the filter โ€” not every post fetched. Raising minEngagement therefore changes the denominator, not just which rows appear, so engagementRate values from two runs with different minEngagement settings aren't directly comparable.

โฌ†๏ธ Output

Every scraped row is pushed to the Actor's dataset as one normalized, typed JSON record with a consistent schema across runs โ€” post rows and summary rows share the same dataset. Export as JSON, CSV, Excel, or any other format the Apify platform's dataset export supports.

Scraped results

[
{
"rowType": "post",
"facebookUrl": "https://www.facebook.com/nytimes/",
"postId": "1397878851694949",
"pageName": "nytimes",
"url": "https://www.facebook.com/100044185428261/posts/1397878851694949",
"time": "2026-07-20T14:03:00.000Z",
"timestamp": 1784642580,
"user": {
"id": "100044185428261",
"name": "The New York Times",
"profileUrl": "https://www.facebook.com/100044185428261",
"profilePic": "https://scontent.xx.fbcdn.net/v/t39.30808-1/nytimes_profile.jpg"
},
"collaborators": [],
"text": "Here's what to know about today's Senate vote.",
"likes": 4022,
"comments": 611,
"shares": 348,
"topReactionsCount": 4022,
"reactionLikeCount": 3102,
"reactionLoveCount": 210,
"reactionHahaCount": 88,
"reactionCareCount": 44,
"reactionSadCount": 402,
"reactionWowCount": 96,
"reactionAngryCount": 80,
"media": [
{
"thumbnail": "https://scontent.xx.fbcdn.net/v/t39.30808-6/senate_thumb.jpg",
"__typename": "Photo",
"__isMedia": "Photo",
"accent_color": "FFFFFFFF",
"photo_product_tags": [],
"photo_image": { "uri": "https://scontent.xx.fbcdn.net/v/t39.30808-6/senate_full.jpg", "height": 720, "width": 1280 },
"url": "https://www.facebook.com/100044185428261/posts/1397878851694949",
"id": "6541234567890"
}
],
"feedbackId": "ZmVlZGJhY2s6MTM5Nzg3ODg1MTY5NDk0OQ==",
"engagementScore": 6288,
"engagementRate": 1.7212,
"dominantReaction": "like",
"reactionMixPct": { "like": 77.13, "love": 5.22, "haha": 2.19, "care": 1.09, "sad": 10.0, "wow": 2.39, "angry": 1.99 },
"captionText": null,
"topLevelUrl": "https://www.facebook.com/100044185428261/posts/1397878851694949",
"facebookId": "100044185428261",
"pageAdLibrary": { "id": "100044185428261" },
"inputUrl": "https://www.facebook.com/nytimes/"
},
{
"rowType": "post",
"facebookUrl": "https://www.facebook.com/nytimes/",
"postId": "1397878851694920",
"pageName": "nytimes",
"url": "https://www.facebook.com/100044185428261/posts/1397878851694920",
"time": "2026-07-18T14:03:00.000Z",
"timestamp": 1784469780,
"user": {
"id": "100044185428261",
"name": "The New York Times",
"profileUrl": "https://www.facebook.com/100044185428261",
"profilePic": "https://scontent.xx.fbcdn.net/v/t39.30808-1/nytimes_profile.jpg"
},
"collaborators": [],
"text": "A quieter news day, but here's our roundup.",
"likes": 890,
"comments": 42,
"shares": 15,
"topReactionsCount": 890,
"reactionLikeCount": 820,
"reactionLoveCount": 40,
"reactionHahaCount": 10,
"reactionCareCount": 8,
"reactionSadCount": 6,
"reactionWowCount": 4,
"reactionAngryCount": 2,
"media": [],
"feedbackId": "ZmVlZGJhY2s6MTM5Nzg3ODg1MTY5NDkyMA==",
"engagementScore": 1019,
"engagementRate": 0.279,
"dominantReaction": "like",
"reactionMixPct": { "like": 92.13, "love": 4.49, "haha": 1.12, "care": 0.9, "sad": 0.67, "wow": 0.45, "angry": 0.22 },
"captionText": null,
"topLevelUrl": "https://www.facebook.com/100044185428261/posts/1397878851694920",
"facebookId": "100044185428261",
"pageAdLibrary": { "id": "100044185428261" },
"inputUrl": "https://www.facebook.com/nytimes/"
},
{
"rowType": "summary",
"pageName": "nytimes",
"facebookUrl": "https://www.facebook.com/nytimes/",
"inputUrl": "https://www.facebook.com/nytimes/",
"postsAnalyzed": 2,
"avgEngagement": 3653.5,
"avgReactions": 2456.0,
"avgComments": 326.5,
"avgShares": 181.5,
"bestPostingHour": 14,
"postingCadenceDays": 2.0,
"topPostUrl": "https://www.facebook.com/100044185428261/posts/1397878851694949"
},
{
"rowType": "post",
"facebookUrl": "https://www.facebook.com/Cristiano/",
"postId": "1029384756102938",
"pageName": "Cristiano",
"url": "https://www.facebook.com/173344912651506/posts/1029384756102938",
"time": "2026-07-21T18:30:00.000Z",
"timestamp": 1784760600,
"user": {
"id": "173344912651506",
"name": "Cristiano Ronaldo",
"profileUrl": "https://www.facebook.com/173344912651506",
"profilePic": "https://scontent.xx.fbcdn.net/v/t39.30808-1/cristiano_profile.jpg"
},
"collaborators": [],
"text": "Great win today, thank you for the support!",
"likes": 40224,
"comments": 2279,
"shares": 1484,
"topReactionsCount": 40224,
"reactionLikeCount": 35000,
"reactionLoveCount": 3600,
"reactionHahaCount": 800,
"reactionCareCount": 400,
"reactionSadCount": 100,
"reactionWowCount": 300,
"reactionAngryCount": 24,
"media": [],
"feedbackId": "ZmVlZGJhY2s6MTAyOTM4NDc1NjEwMjkzOA==",
"engagementScore": 49234,
"engagementRate": 1.0,
"dominantReaction": "like",
"reactionMixPct": { "like": 87.03, "love": 8.95, "haha": 1.99, "care": 0.99, "sad": 0.25, "wow": 0.75, "angry": 0.06 },
"captionText": null,
"topLevelUrl": "https://www.facebook.com/173344912651506/posts/1029384756102938",
"facebookId": "173344912651506",
"pageAdLibrary": { "id": "173344912651506" },
"inputUrl": "https://www.facebook.com/Cristiano/"
}
]

How can I use the data extracted with Facebook Posts Scraper โ€” Engagement Analytics Report?

  • Social media managers: use dominantReaction and reactionMixPct to see whether a post is landing as intended (mostly love) or backfiring (a spike in angry or sad) without opening each post individually.
  • Content strategists: use engagementRate, bestPostingHour, and postingCadenceDays from the summary row to see which posts beat the page's own baseline and when the page publishes its best-performing content.
  • Competitive analysts: run pageUrls across your own page and competitor pages in one job, then compare each page's avgEngagement and topPostUrl summary fields for a quick benchmark of who's winning engagement this period.
  • AI engineers and LLM developers: have an agent call the Actor with a page URL, receive text, engagementScore, and dominantReaction as structured JSON, and pass it straight into a model as grounded context โ€” no separate scoring step needed.

How do you monitor Facebook Page engagement over time?

Monitoring here means running the same pageUrls on a recurring schedule and diffing the engagement fields between runs, rather than reading one snapshot. Because each post keeps its stable postId across runs, you can match a post between two runs and watch engagementScore, engagementRate, and the individual reaction counts change as it ages, or watch for a new postId appearing at the top of the feed. At the page level, compare each run's summary row โ€” a rising avgEngagement or a shifting bestPostingHour/postingCadenceDays between two runs tells you the page's posting behavior or audience response has genuinely changed, not just that one post did well.

A typical workflow: schedule a run across your tracked pageUrls (for example, weekly), pull the previous run's dataset via the Apify API, join both datasets on postId for post rows and on pageName for summary rows, and compute the delta on engagementScore and avgEngagement. Alert when a post's score jumps well past its page's engagementRate of 1.0, or when bestPostingHour shifts significantly from the prior run.

Facebook Posts Scraper โ€” Engagement Analytics Report does not include a built-in scheduler of its own, but every Apify Actor โ€” including this one โ€” can be attached to Apify's platform-level Schedule feature (cron-style, configured in the Apify Console or via the API) to run automatically on an interval; combine that with the Apify API's dataset endpoints to pull and diff each run's results.

Integrate Facebook Posts Scraper โ€” Engagement Analytics Report and automate your workflow

Facebook Posts Scraper โ€” Engagement Analytics Report works with any language or tool that can send an HTTP request to the Apify API.

REST API with Python

import requests
TOKEN = "<YOUR_APIFY_TOKEN>"
url = "https://api.apify.com/v2/acts/scrapier~facebook-posts-scraper-engagement-analytics-report/run-sync-get-dataset-items"
payload = {
"pageUrls": ["nytimes", "https://www.facebook.com/Cristiano/"],
"postsPerPage": 50,
"minEngagement": 0,
}
resp = requests.post(url, params={"token": TOKEN}, json=payload, timeout=180)
rows = resp.json()
posts = [r for r in rows if r.get("rowType") == "post"]
for post in posts:
print(post["pageName"], post["engagementScore"], post["dominantReaction"])

MCP for query-grounded AI agents

Facebook Posts Scraper โ€” Engagement Analytics Report can be exposed to an MCP-compatible agent through Apify's Actors MCP Server: run npx @apify/actors-mcp-server --tools scrapier/facebook-posts-scraper-engagement-analytics-report locally with an APIFY_TOKEN environment variable, or connect the hosted server at https://mcp.apify.com and authorize it via OAuth. Once registered, an agent in Claude Desktop, Claude Code, Cursor, or another MCP client can call the Actor as a tool, receive the scored post and summary JSON back, and ground its answer in a page's real recent engagement instead of stale training data.

Scheduled monitoring and delivery

There is no actor-specific webhook feature documented in this Actor's own configuration; instead, attach it to Apify's platform-level Schedule to trigger runs on an interval, and use the Apify API's run-finished webhooks or dataset export endpoints to deliver each run's post and summary rows to your own storage or pipeline.

Yes โ€” scraping publicly accessible Facebook Page posts is generally lawful in the US; courts have held that accessing data a site makes available to any visitor, without bypassing an access barrier, does not violate the Computer Fraud and Abuse Act (hiQ Labs, Inc. v. LinkedIn Corp., 9th Cir., 2019). Facebook Posts Scraper โ€” Engagement Analytics Report returns only what a logged-out visitor to a public page already sees. Each post's user object (name, profile ID, profile picture) is personal data, so storing it at scale can fall under GDPR or CCPA depending on your jurisdiction. Periodic engagement monitoring carries a different risk profile than training a model on personal data, and Facebook's Terms of Service separately restrict automated collection. Consult your legal team before any commercial use case involving bulk storage.

Frequently asked questions

Does Facebook Posts Scraper โ€” Engagement Analytics Report require a Facebook account or login?

No. The input schema has no login or cookie field at all โ€” public pages are read the same way a logged-out browser would, through Apify's residential proxy by default.

How do I control which posts get scored?

Use postsPerPage to set the sample size, minEngagement to drop low-scoring posts before they're emitted or averaged, and postsFrom/postsUntil to bound the sample to a date window.

How does Facebook Posts Scraper โ€” Engagement Analytics Report handle Facebook's anti-bot measures?

It sends requests with Chrome-like TLS/HTTP fingerprints (via the impit client) with a plain-requests fallback, retries with exponential backoff on blocked or empty responses (403, 429, 999, or empty batches, up to five consecutive empties), and automatically prefers Apify's residential proxy with a datacenter fallback.

Does the engagement analytics report compute rank or percentile scores?

No. It computes engagementScore, an engagementRate normalized against that page's own average for the run, dominantReaction, and reactionMixPct per post, plus avgEngagement, bestPostingHour, and postingCadenceDays per page. It does not output a rank-within-result-set or percentile field โ€” engagementRate is a ratio to the page's own average, not a rank or percentile position.

Does minEngagement affect engagementRate?

Yes. minEngagement removes posts before the page average is computed, so engagementRate is always normalized against only the posts that survive the filter for that page, not every post the Actor fetched.

How many posts can I analyze per page?

postsPerPage defaults to 10 with no schema-enforced maximum below 1,000,000, but each page run is bounded by an internal pagination-request cap (60โ€“200 requests depending on sample size and whether transcripts are on) and a timeout that auto-scales between roughly 360 and 5,400 seconds (or 60โ€“7,200 seconds in manual mode) โ€” very large samples may not complete within a single run.

How do I use Facebook Posts Scraper โ€” Engagement Analytics Report to monitor Facebook Page engagement over time?

Schedule the same pageUrls to run on an interval via Apify's Schedule feature, pull each run's dataset, match post rows by postId and summary rows by pageName, and compare engagementScore and avgEngagement to the previous run โ€” alert when a delta crosses whatever threshold matters to you.

Does Facebook Posts Scraper โ€” Engagement Analytics Report work with Claude, ChatGPT, and AI agent frameworks?

Yes. It is callable as a plain HTTP endpoint from any agent framework, and it is also reachable through Apify's Actors MCP Server (npx @apify/actors-mcp-server --tools scrapier/facebook-posts-scraper-engagement-analytics-report, or the hosted https://mcp.apify.com server) for MCP-native clients such as Claude Desktop and Claude Code.

How does Facebook Posts Scraper โ€” Engagement Analytics Report compare to other Facebook post scrapers?

As observed on their public Apify Store listings on 2026-07-26: api-empire/facebook-page-posts-scraper returns reaction, comment, and share totals plus a per-type breakdown but no computed score, rate, or page-level averages โ€” it leaves scoring to you. scraper-engine/facebook-page-posts-scraper-with-engagement-analytics goes further than this Actor, additionally computing a rankInResultSet, an engagementPercentile, and an age-adjusted viralityScore. Facebook Posts Scraper โ€” Engagement Analytics Report sits between the two: it adds a weighted score, a page-average-normalized rate, reaction-mix analytics, and a page summary row on top of the raw counts, without a rank or percentile field.

Can I use Facebook Posts Scraper โ€” Engagement Analytics Report without managing proxies or Facebook credentials?

Yes. The Actor prefers Apify's residential proxy and falls back to datacenter proxy automatically โ€” there is no login credential to supply anywhere in the input schema.

Your feedback

Found a bug or a field that doesn't match what's documented here? Let us know through Scrapier's Apify Store support tab or issue tracker โ€” reports like this go straight into the next update.