Facebook Posts Search Scraper: Content Calendar Analysis
Pricing
from $4.99 / 1,000 results
Facebook Posts Search Scraper: Content Calendar Analysis
๐ Facebook Posts Search Scraper extracts public posts by keyword, hashtag, or date โ capturing text, author, URL, reactions, comments & shares. ๐ Ideal for social listening, trend analysis, and competitor research. Export CSV/JSON, schedule, and scale via API. ๐
Pricing
from $4.99 / 1,000 results
Rating
0.0
(0)
Developer
API Empire
Maintained by CommunityActor stats
0
Bookmarked
7
Total users
0
Monthly active users
5 days ago
Last modified
Categories
Share
Facebook Posts Scraper โ Extract Posts, Page Rollups and Rankings
Facebook Posts Search Scraper: Content Calendar Analysis discovers public Facebook posts by keyword or competitor name and returns three linked outputs: matching posts, a per-page engagement rollup, and a competitor ranking table. Every response is typed, normalized JSON โ no HTML, no selectors, no parsing. Point it at a topic, brand, or rival page name, and it finds matching posts, groups them by the Facebook Page that published them, and ranks any competitors you list by likes, comments, and shares.
What is Facebook Posts Search Scraper: Content Calendar Analysis?
Facebook Posts Search Scraper: Content Calendar Analysis is an Apify Actor that finds public Facebook posts matching one or more search keywords, brand names, or competitor page names โ no Facebook account or login required. It then automatically rolls up the matching posts per Facebook Page (post count, average engagement, top-performing post) and, when you list pages to compare, ranks them side by side on engagement. Optional add-ons enrich pages with follower/category data, page contact details, and post comments.
- Discover posts by keyword, brand, or competitor/page name across public Facebook
- Roll up matching posts per Facebook Page: post count, average likes/comments/shares, top post
- Rank a custom list of competitor pages side by side on engagement
- Optionally enrich pages with followers/category, page contact details, or post comments
- Export as JSON or CSV, or read results via the Apify API
What data does Facebook Posts Search Scraper: Content Calendar Analysis collect?
The Actor returns four distinct data types from a single run: the discovered posts themselves, a per-page rollup, an optional competitor ranking, and optional child datasets for comments and contact details.
| Data Type | Key Fields | JSON Field Names |
|---|---|---|
| Posts | page, engagement, caption text, media, timestamp | pageName, likes, comments, shares, text, thumb, timestamp |
| Page Summary (rollup) | post count, average engagement, top post, optional followers/category | postCount, avgLikes, avgComments, topPostUrl, followersCount, pageCategory |
| Comparison Ranking | rank, posts found, engagement score per competitor | rank, engagementScore, avgLikes, postsFound |
| Comments (child dataset) | comment text, author, likes, replies | commentText, authorName, likesCount, repliesCount |
| Page Contact (lead data) | email, phone, website, address | contact.email, contact.phone, contact.website, contact.address |
Need more Facebook data?
If you need a deep dive on one Page's content strategy rather than keyword discovery across many pages, Facebook Posts Scraper: Content Strategy Insights classifies every post's content type, hashtags, and calls-to-action for a single Page's timeline. If you need full comment threads rather than the top-level comments this Actor collects, Facebook Comments Scraper With Author Lead Enrichment pulls deeper comment data with commenter profile enrichment.
How does Facebook Posts Search Scraper differ from the official Facebook API?
Meta's Graph API requires a registered Meta app, App Review, and โ for most Page-content permissions โ Business Verification before it returns any Page posts, and it has no endpoint for keyword search across arbitrary public pages; access is scoped to Pages and accounts your app has been explicitly granted. Facebook Posts Search Scraper instead discovers public posts directly from a keyword or page name, with no app review and no per-page permission grant.
| Feature | Facebook Graph API | Facebook Posts Search Scraper |
|---|---|---|
| Access setup | Meta App Review + Business Verification | No account, no app registration |
| Keyword search across pages | Not supported โ no public post-search endpoint | Core feature: search by keyword or competitor name |
| Scope of accessible posts | Pages/accounts your app is granted access to | Any public Facebook post discoverable via search |
| Page/competitor rollups | Not provided โ build it yourself from raw responses | Built-in per-page rollup and competitor ranking |
| Setup time | Review process required before first call | Fill in input, run |
| Output consistency | Raw Graph API JSON, versioned per endpoint | Stable typed JSON schema, same fields every run |
The Graph API is the right choice if you manage the Pages in question and need officially permissioned access to your own Page analytics. Facebook Posts Search Scraper is the practical choice when you need to discover and compare posts from pages you don't manage, without going through an app review process.
Why do developers and teams scrape Facebook?
For marketers and brand teams
Marketers use comparePages to list a handful of competitor page names or search queries and get back a ranked COMPARISON-RANKING table sorted by engagementScore โ the fastest way to see whose posts about a topic are landing best this week. Combined with the per-page PAGE-SUMMARY rollup, a brand team can track its own page's avgLikes/avgComments/avgShares against named rivals without manually opening each competitor's Page and counting reactions by hand. Re-running the same competitorQueries on a schedule turns this into ongoing competitor-monitoring rather than a one-off snapshot, feeding a recurring content or campaign review.
For researchers and analysts
Researchers studying public discourse around a topic, event, or brand can search by keyword rather than by page, so the dataset isn't limited to accounts they already know about. Each post row carries timestamp, text, and engagement counts, giving a public, citation-ready sample of how a topic is being discussed across different Facebook Pages โ useful for tracking sentiment or reach trends without accessing any private profile or gated group content. The postRecencyWindow filter lets a study scope its sample to a fixed recent window, and searchQuery on every row records which term produced each post for later cross-tabulation.
For AI engineers and agent builders
Agent builders can wire competitorQueries as a tool parameter so an LLM agent decides what to search for, then pass the returned text, likes, comments, and shares fields directly into a RAG index or a summarization prompt โ no HTML cleanup step. Because output is stable typed JSON with the same keys on every run, an agent can reliably parse PAGE-SUMMARY records to answer questions like "which page posts about this topic gets the most engagement?" without brittle scraping logic.
For developers building data products
Developers building a competitor-monitoring product or a lead-gen tool can schedule this Actor on a recurring basis, pass different competitorQueries per customer, and store the resulting posts, page rollups, and optional contact records in their own database. The optional enableContactLookup and maxCommentsPerPost fields let a data product add email/phone/website leads and comment-level detail on top of the base post-and-rollup pipeline, all from the same run. Because every field name and type stays fixed between runs, downstream ingestion code can be written once and left alone as the underlying scrape logic evolves.
How to scrape Facebook (step by step)
- Open Facebook Posts Search Scraper: Content Calendar Analysis on its Apify Store listing and start a new run.
- Provide
competitorQueriesโ the keywords, brand names, or competitor page names to search for (none are strictly required; the Actor defaults tofootballif left empty). - Set filters:
maxPostsPerQueryto cap results per query,postRecencyWindowto limit by recency, andcomparePagesif you want a ranked comparison table. - Start the run.
- Download the post dataset as JSON or CSV, and read the
PAGE-SUMMARY/COMPARISON-RANKINGrecords from the run's Key-Value Store for the rollups.
What to do when Facebook changes its structure
Facebook Posts Search Scraper is actively maintained, and its output schema is kept stable โ field names and types don't change on your end even when the underlying extraction logic needs updates on ours. No specific turnaround time is promised for any given fix.
โฌ๏ธ Input
Required per the input schema: none โ every field below is optional, and the Actor runs with sensible defaults if you provide nothing.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
competitorQueries | No | array | Search keywords or competitor/page names to discover posts for. Each entry runs as a separate search. | ["nike", "adidas"] |
maxPostsPerQuery | No | integer | Posts to collect per keyword/competitor. Range 1โ5000; leave empty for the default of 50. | 20 |
postRecencyWindow | No | string (enum) | Recency filter: "" (all time, default), 24h, 7d, 30d, 90d. | "7d" |
enablePageSummary | No | boolean | Group discovered posts by page and emit one summary record per page (post count, avg engagement, top post) to Key-Value Store record PAGE-SUMMARY. Default: on (code default true). | true |
enablePageProfileEnrichment | No | boolean | Fetch each distinct page's public profile once to add follower count and category to the page summary. Default: off. | false |
comparePages | No | array | Page names, page URLs, or queries to rank side by side on engagement in Key-Value Store record COMPARISON-RANKING. Leave empty to disable. | ["nike", "adidas"] |
targetCountry | No | string (enum) | Bias the discovery search toward a country's results (SERP gl param). Blank = no bias (default). | "us" |
targetLanguage | No | string (enum) | Language for the discovery search (SERP hl param). Blank = English (default). | "en" |
enableContactLookup | No | boolean | Fetch each post's Facebook Page and extract public email/phone/website/address into contact. Missing fields are null, never fabricated. Default: false. | false |
maxCommentsPerPost | No | integer | Top-level comments to fetch per post (0โ500), saved to an uncharged comments-<runId> dataset. 0 (default) disables it. | 0 |
proxyConfiguration | No | object | Proxy settings for Facebook requests. Default: { "useApifyProxy": true }. | { "useApifyProxy": true } |
Example input:
{"competitorQueries": ["nike", "adidas"],"maxPostsPerQuery": 20,"postRecencyWindow": "","enablePageSummary": true,"enablePageProfileEnrichment": false,"comparePages": ["nike", "adidas"],"targetCountry": "","targetLanguage": "","enableContactLookup": false,"maxCommentsPerPost": 0,"proxyConfiguration": { "useApifyProxy": true }}
The most common input mistake is listing the same names in both competitorQueries and comparePages expecting two separate result sets โ the Actor de-duplicates any comparePages entry that already appears in competitorQueries, so put every page/query you want ranked into comparePages and leave competitorQueries for the ones you only want discovered.
โฌ๏ธ Output
Every run produces typed, normalized JSON exported as JSON or CSV from the dataset, plus two optional rollups written to the run's Key-Value Store. Only post rows in the primary dataset are charged (row_result); the PAGE-SUMMARY and COMPARISON-RANKING records and the child comments dataset add no extra charge.
Scraped Posts (primary dataset)
{"facebookUrl": "https://www.facebook.com/nike","pageId": "15087023444","pageName": "Nike","facebookId": "15087023444","postId": "826453901928374","postFacebookId": "826453901928374","url": "https://www.facebook.com/nike/posts/826453901928374","topLevelUrl": "https://www.facebook.com/nike/posts/826453901928374","time": "2026-07-18 14:32:05","timestamp": 1784385125,"likes": 18420,"comments": 612,"shares": 340,"text": "New drop. Just do it.","link": "https://www.facebook.com/nike/posts/826453901928374","thumb": "https://scontent.fxyz1-1.fna.fbcdn.net/v/example.jpg","contact": { "email": null, "phone": null, "website": null, "address": null },"commentsFetched": 0,"scrapedAt": "2026-07-25T09:12:44.109384+00:00","searchQuery": "nike","isComparisonTarget": true}
Page Summary (Key-Value Store record PAGE-SUMMARY)
{"pageId": "15087023444","pageName": "Nike","facebookUrl": "https://www.facebook.com/nike","postCount": 20,"avgLikes": 15230.45,"avgComments": 480.2,"avgShares": 265.8,"totalLikes": 304609,"totalComments": 9604,"totalShares": 5316,"topPostUrl": "https://www.facebook.com/nike/posts/826453901928374","topPostLikes": 18420,"searchQueries": ["nike"],"followersRaw": "42M","followersCount": 42000000,"pageCategory": "Sportswear store","likesFromProfile": 41000000}
Comparison Ranking (Key-Value Store record COMPARISON-RANKING)
{"query": "nike","postsFound": 20,"avgLikes": 15230.45,"avgComments": 480.2,"avgShares": 265.8,"totalLikes": 304609,"totalComments": 9604,"totalShares": 5316,"engagementScore": 15976.45,"matchedPageNames": ["Nike"],"rank": 1}
Post Comments (uncharged child dataset comments-<runId>, when maxCommentsPerPost > 0)
{"parentPostId": "826453901928374","parentPostUrl": "https://www.facebook.com/nike/posts/826453901928374","commentId": "Y29tbWVudDoxMjM0NTY3ODk=","feedbackId": "ZmVlZGJhY2s6ODI2NDUzOTAxOTI4Mzc0","commentUrl": "https://www.facebook.com/nike/posts/826453901928374?comment_id=123456789","commentDate": "2026-07-18T15:02:11+00:00","commentText": "Love these!","authorName": "Jordan Smith","authorId": "100004455667788","authorProfileUrl": "https://www.facebook.com/jordan.smith","authorProfilePicture": "https://scontent.fxyz1-1.fna.fbcdn.net/v/profile.jpg","likesCount": 12,"repliesCount": 2,"threadingDepth": 0,"facebookCommentId": "123456789","keyword": "nike","isChild": true,"type": "comment","scrapedAt": "2026-07-25T09:13:02.552112+00:00"}
How many results can you scrape with Facebook Posts Search Scraper?
maxPostsPerQuery caps results at up to 5,000 posts per search query, with a default of 50 if left blank; there is no hard cap on the number of queries you can list in competitorQueries or comparePages, so total posts scale with however many queries you run. Internally, discovery paginates Google search result pages (10 Facebook URLs per page) up to a capped number of pages per query, stopping early once the target count is reached or after three consecutive empty result pages. maxCommentsPerPost separately caps top-level comments fetched per post at up to 500, written to an uncharged child dataset. Facebook itself does not publish a documented limit on how many of its posts are indexable through search, so the practical ceiling for any one query is whatever the discovery search surfaces. No benchmark run time is published โ actual duration depends on how many optional enrichments (comments, contact lookup, profile enrichment) are enabled alongside the post count.
Integrate Facebook Posts Search Scraper and automate your workflow
Facebook Posts Search Scraper works with any language or tool that can send an HTTP request, since it runs as a standard Apify Actor.
REST API integration
from apify_client import ApifyClientclient = ApifyClient("<APIFY_API_TOKEN>")run = client.actor("<owner>/facebook-posts-search-scraper-content-calendar-analysis").call(run_input={"competitorQueries": ["nike", "adidas"],"maxPostsPerQuery": 20,"comparePages": ["nike", "adidas"],})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["pageName"], item["likes"], item["comments"])
Works in Python, Node.js, Go, Ruby, cURL.
MCP for AI agents
Apify's MCP server (mcp.apify.com) exposes Apify Actors โ including this one โ as callable tools for MCP-compatible clients such as Claude Desktop, Cursor, and Windsurf. Add the Actor's name (as shown on its Apify Store page) to the server's actor list to make it callable as an agent tool without writing custom integration code.
Automation platforms (n8n, Make, LangChain)
In n8n, the community Apify node's "Run Actor" operation can call Facebook Posts Search Scraper by Actor ID and pass competitorQueries/maxPostsPerQuery as JSON, then feed the resulting dataset items and PAGE-SUMMARY record into downstream nodes. In Make, the Apify app's "Run an Actor or Task" module runs the same Actor and lets you map each returned post row into another scenario step, such as a spreadsheet row or a Slack alert when a competitor's engagementScore changes. Any LangChain agent that can call an HTTP tool can invoke the Actor through the Apify API and consume its dataset items directly as typed JSON, without a parsing step.
Is it legal to scrape Facebook?
Scraping publicly accessible Facebook data is generally lawful, and Facebook Posts Search Scraper only returns posts and page information visible to a logged-out visitor โ no private profiles, no login-gated groups. Most output (post text, engagement counts, page name/category) is business or organizational data governed primarily by Facebook's Terms of Service rather than personal-data law. Two optional features do return personal data: enableContactLookup can surface a Page's public contact details, and maxCommentsPerPost returns commenters' names, IDs, and profile URLs โ this is personal data subject to GDPR/CCPA-style requirements around a lawful basis for storage and use. Consult legal counsel for commercial use cases involving bulk personal data.
Frequently asked questions
Does Facebook Posts Search Scraper work without a Facebook account?
Yes. It discovers posts through public search and fetches each post's public page HTML directly โ no Facebook login or account is required.
Is "content calendar analysis" a real posting-cadence feature?
Not in the sense of computed posting-frequency or day/hour scheduling patterns โ the Actor does not bucket posts by day of week, time of day, or posting interval. What it does compute, from the real scraped rows, is a per-page rollup (postCount, avgLikes, avgComments, avgShares, topPostUrl) and a competitor engagement ranking. Every post row also carries a timestamp, so you can build your own cadence analysis on top of the output, but that bucketing isn't done for you today.
How often is the scraped data updated?
Every run performs a live search and live page fetch โ nothing is served from a cache. Re-run the Actor to get current engagement counts and newly published posts.
What happens if a post is removed or a query returns no results?
If a post becomes unavailable mid-run, the fetch is skipped and logged as a warning; other posts in the same run are unaffected. If a query returns zero discoverable Facebook URLs (for example, if the search provider blocks the request), the Actor logs a warning and returns an empty result for that query rather than failing the whole run.
Can I scrape private or login-gated Facebook content?
No. Only content visible to a logged-out visitor is returned โ private profiles and login-gated groups are out of scope.
Does Facebook Posts Search Scraper work for AI agent workflows and LLM pipelines?
Yes. It's callable as an HTTP endpoint from any agent framework, and it's reachable through Apify's MCP server for MCP-compatible clients. Every response is typed JSON with stable field names โ no HTML, no parsing step before passing results into an LLM context or a RAG index.
How does Facebook Posts Search Scraper handle Facebook's anti-bot measures?
Discovery requests route through Apify's GOOGLE_SERP proxy group, page fetches use Apify Proxy (datacenter/residential as configured) with browser-like request headers, and each HTML fetch retries up to three times with exponential backoff on transient errors. Comment fetches use a residential proxy session when available.
Does Facebook Posts Search Scraper return data in a format LLMs can use directly?
Yes. Typed, normalized JSON with stable field names on every run โ pass it directly into an LLM context window, index it into a vector store, or route it through an agent tool without a parsing step.
Can I use Facebook Posts Search Scraper without managing proxies?
Yes. Apify Proxy is enabled by default (useApifyProxy: true), and the search-discovery step always uses Apify's GOOGLE_SERP proxy group regardless of your proxyConfiguration setting.
What happens when Facebook changes its structure or blocks the scraper?
The Actor is actively maintained, and its output schema stays stable โ field names and types don't change on your end when the underlying extraction logic is updated. No numeric turnaround time is promised for any given fix.
Your feedback
Found a bug or missing a field? We want to know. Reach out through the Actor's Apify Store page or issue tracker so we can look into it โ active maintenance is how this Actor stays reliable as Facebook's page structure evolves.