Facebook Post Search Scraper - Keyword Search avatar

Facebook Post Search Scraper - Keyword Search

Pricing

from $2.08 / 1,000 posts

Go to Apify Store
Facebook Post Search Scraper - Keyword Search

Facebook Post Search Scraper - Keyword Search

Search public Facebook posts by keyword or hashtag. Get post text, URL, author, date, reactions by type, comments, shares, media and group for social listening. No login.

Pricing

from $2.08 / 1,000 posts

Rating

0.0

(0)

Developer

Automation Lab

Automation Lab

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

5

Monthly active users

16 hours ago

Last modified

Security

Limited permissions

Share

Search public Facebook posts by keyword or hashtag and export one clean row per post: full text, post URL, author Page or profile, publish date, reactions by type, comments, shares, video views, photos and videos, outbound links, public group and reshare details.

The Actor runs Facebook's own post search exactly as a signed-out visitor sees it. No Facebook login, cookies or API key are needed, and you can search many keywords in one run, with Facebook's Top ranking or its Recent posts filter.

What does Facebook Post Search Scraper do?

You give it a list of search queries such as coffee, #blackfriday or plumber near me. For each query the Actor:

  1. Runs Facebook's public Posts search for that query, with Facebook's Top ranking or its Recent posts filter.
  2. Follows the result pages (about 10-12 posts per page) until it reaches your limit or Facebook has no more pages.
  3. Turns every post into a structured row with the text, author, date, engagement numbers, media and group.
  4. Applies your filters (date window, words that must appear, groups vs. Pages, post type, minimum reactions) before saving, so you only pay for posts you keep.

The run's status message says how many posts were saved per query and why each query stopped, for example "coffee": 100 of 100 (maxPostsPerQuery reached) or "plumber near me": 11 of 30 (Facebook returned no more result pages).

Who is it for?

  • Social listening and brand teams tracking public mentions of a brand, product or competitor on Facebook.
  • Marketing and campaign researchers studying which public posts about a topic or hashtag get the most reactions, comments and shares.
  • Lead generation teams finding public group posts such as "looking for a plumber" or "recommend a dentist" and the people asking.
  • Journalists and analysts collecting public discussion about an event, a product launch or a news topic.
  • Data and AI teams building datasets of public Facebook posts for classification, sentiment or summarisation.

Why use this Facebook post search scraper?

  • Facebook's own post search, not a crawl of a few Pages: results come from every public Page, profile and public group Facebook matches.
  • Every engagement number on every row: total reactions plus the like / love / care / haha / wow / sad / angry breakdown, comments, shares, and views for videos.
  • Rich media and context: all photos of an album with captions, video URL, duration and thumbnail, unwrapped outbound links with title and domain, public group name and URL, reshare details and hashtags.
  • Pay only for posts you keep: posts removed by your date window, word-match, source, type or reaction filters are never saved, so they cost nothing.
  • matchesQuery on every row tells you whether the post text really contains your words, because Facebook also ranks loosely related posts.
  • Many keywords per run, searched in parallel, each with its own limit and stop reason.
  • No login: nothing to renew, no account at risk.
FieldWhat it contains
postId, urlFacebook post ID and public permalink
textFull post text, never truncated
publishedAt, timestampPublish time (ISO 8601 UTC and Unix milliseconds)
authorName, authorId, authorUrl, authorPage or profile that posted, with profile picture
reactionsCount, reactionsTotal reactions and the count per reaction type
commentsCount, sharesCount, engagementCountComments, shares, and reactions + comments + shares
videoViewCountViews for video posts
postTypephoto, album, video, link, share, text or other
media, mediaCount, imageUrlPhotos and videos with URL, image, size, caption and duration
externalLinkOutbound link (unwrapped from Facebook's redirect) with title, domain and preview image
isGroupPost, groupId, groupName, groupUrlPublic group the post was made in
isReshare, sharedPostOriginal post of a reshare: ID, URL, text, author, date
privacyAudience label, such as Public
hashtagsHashtags parsed from the text
searchQuery, sortBy, searchRankWhich query and sort found the post, and its position in Facebook's results
matchesQueryWhether every query word appears in the post
scrapedAtWhen the row was produced

On a 200-post test run for coffee and #blackfriday, every row had a URL, date, author, reactions with the per-type breakdown, comments and shares; 96% had an image, 19% were videos with view counts, 18% came from public groups, 62% had hashtags and 79% contained the query word.

How much does it cost to scrape Facebook posts by keyword?

The Actor uses pay-per-event pricing. You pay a small fee per run plus a fee for every post saved to your dataset. Posts removed by your filters are free. Platform usage (compute and proxy) is included in the price.

EventFree / Starter (Bronze)Scale (Silver)Business (Gold) and higher
Run start (once per run)$0.0005$0.0005$0.0005
Post saved$0.0026$0.00234$0.00208

Examples on the Starter plan:

  • 20 posts for one keyword: about $0.05
  • 100 posts for one keyword: about $0.26
  • 5 keywords × 100 posts in one run: about $1.30
  • 1,000 posts: about $2.60

With Apify's free plan credit of $5 a month you can collect roughly 1,900 posts a month. You can set a maximum cost per run in the run options; the Actor stops cleanly when it is reached.

How to scrape Facebook posts by keyword

  1. Open the Actor in Apify Console and click Try for free.
  2. Enter your keywords or hashtags under Search queries, one per line.
  3. Choose Sort by: Top posts for research, Recent posts for monitoring.
  4. Set Max posts per query, and optionally a date window or other filters.
  5. Click Start. Posts appear in the dataset as each page of results arrives.
  6. Export the results as JSON, CSV, Excel or HTML, or connect them to your tools through the API and integrations.

Input parameters

ParameterTypeDefaultDescription
searchQueriesarray of stringsrequiredKeywords, phrases or hashtags, one search each. A facebook.com/search/posts/?q=... URL also works.
sortBytop or recenttopFacebook's relevance ranking, or its Recent posts filter (mostly recent posts; rows keep Facebook's order, which is not strictly by date).
maxPostsPerQueryinteger 1-100020Posts saved per query after filters.
maxItemsinteger0Cap on posts across the whole run. 0 = no run-wide cap.
startDatestring-Keep posts published on or after this UTC date: 2026-09-01, 7 days, 3 weeks, 2 months.
endDatestring-Keep posts published on or before this UTC date (whole day included).
mustContainQuerybooleanfalseKeep only posts where every query word appears in the text, shared post text or link title.
postSourceall, groups, pages_and_profilesallOnly public group posts, or only Page and profile posts.
postTypeall, photo, album, video, link, share, textallKeep one kind of post.
minReactionsinteger0Keep only posts with at least this many reactions.
proxyConfigurationobjectApify datacenter (SHADER)Proxy used for all requests. The default is the tested setting. If Facebook keeps rate-limiting another Apify Proxy setting or no proxy, the run switches to SHADER. Your own proxy URLs are never replaced.

Example input

{
"searchQueries": ["coffee", "#blackfriday"],
"sortBy": "recent",
"startDate": "7 days",
"maxPostsPerQuery": 100,
"mustContainQuery": true
}

Output example

One real row from a coffee search (image URL query strings shortened):

{
"postId": "122181808466805270",
"url": "https://www.facebook.com/reel/1819617662436200/",
"searchQuery": "coffee",
"sortBy": "top",
"searchRank": 4,
"postType": "video",
"text": "Honey butter latte 🍯🧈✨\nCreamy and delicious 😋 \n\nRecipe :\nPiece of butter \n1 tbsp of honey \nPinch of sea salt \n2 shots of espresso \n5 oz of milk\nIce and shake it \nSalted honey cold foam :\n3 tbsp of heavy cream + 2 tbsp of milk + 1/2 tbsp of honey + pinch of sea salt, froth it until thick \n\n#honeylatte #homecafe #coffee #saltedhoneylatte #honeybutter",
"publishedAt": "2026-11-01T19:01:36.000Z",
"timestamp": 1793559696000,
"authorName": "Rafa Coffee",
"authorId": "61574158104501",
"authorUrl": "https://www.facebook.com/people/Rafa-Coffee/61574158104501/",
"author": {
"id": "61574158104501",
"name": "Rafa Coffee",
"url": "https://www.facebook.com/people/Rafa-Coffee/61574158104501/",
"profilePictureUrl": "https://scontent-sjc6-1.xx.fbcdn.net/v/t39.30808-1/697792868_122165764160805270_267460172165753330_n.jpg"
},
"reactionsCount": 639,
"reactions": {
"like": 592,
"love": 40,
"care": 4,
"haha": 0,
"wow": 3,
"sad": 0,
"angry": 0
},
"commentsCount": 4,
"sharesCount": 45,
"videoViewCount": 14246,
"engagementCount": 688,
"imageUrl": "https://scontent-sjc6-1.xx.fbcdn.net/v/t51.71878-10/886224517_2025997718082461_2009185281563289073_n.jpg",
"media": [
{
"type": "video",
"id": "1819617662436200",
"url": "https://www.facebook.com/reel/1819617662436200/",
"imageUrl": "https://scontent-sjc6-1.xx.fbcdn.net/v/t51.71878-10/886224517_2025997718082461_2009185281563289073_n.jpg",
"width": 1080,
"height": 1920,
"caption": null,
"durationSeconds": 29.7
}
],
"mediaCount": 1,
"externalLink": null,
"isGroupPost": false,
"groupId": null,
"groupName": null,
"groupUrl": null,
"isReshare": false,
"sharedPost": null,
"privacy": "Public",
"hashtags": [
"honeylatte",
"homecafe",
"coffee",
"saltedhoneylatte",
"honeybutter"
],
"matchesQuery": true,
"scrapedAt": "2026-11-04T07:54:28.454Z"
}

Tips and limits

  • Use one keyword or short phrase per query. Facebook matches loosely and also ranks related posts. Single words usually match well; long phrases rarely appear verbatim. Turn on mustContainQuery when every row must contain your words.
  • Use recent for monitoring and top for research. top returns popular posts of any age; recent switches on Facebook's Recent posts filter, which favours fresh posts. Rows keep Facebook's own order, which is roughly but not strictly newest-first, so sort by publishedAt yourself if you need exact date order. Schedule a recent run with startDate: "1 day" for a daily feed of fresh mentions.
  • How many posts per query? With top, broad terms easily return 100+ posts (100 of 100 for coffee and #blackfriday in our tests). With recent, Facebook serves fewer pages: about 60-90 posts per query in our tests (65 for electric vehicles, 75 for tesla). Niche terms and narrow date windows return fewer. The run stops when Facebook has no more pages or a per-query page limit is reached, and says which in the status message. A narrow date window or strict filters can hit the page limit before Facebook runs out of pages.
  • Date windows are exact. The window is sent to Facebook's own date filter and checked again on every post.
  • Public content only. The Actor sees what a signed-out visitor sees: public Pages, public profiles and public groups. Private groups and friends-only posts are never included.
  • No location filter. Facebook's tagged-location filter is not available to signed-out visitors, so the Actor does not offer it.
  • Comments are counts only. Use a comments scraper on the post URLs when you need the comment texts.
  • Failures are reported, not hidden. If Facebook refuses a query after several fresh sessions, that query is marked failed in the status message; the run fails only when no posts were saved and every query failed. Posts already saved are always kept.

Integrations

  • Google Sheets or Excel: export the dataset, or use the Apify Google Sheets integration to append new posts after each scheduled run.
  • Slack, email and webhooks: trigger a webhook when a run finishes and send new posts with high engagementCount to a channel.
  • Make, Zapier and n8n: start the Actor from a workflow and route posts into a CRM or ticketing tool, for example group posts asking for a service.
  • Data warehouses and BI: load the JSON or CSV into BigQuery, Snowflake or your BI tool and chart reactions and shares over time.
  • AI pipelines: feed text, reactions and hashtags to an LLM for sentiment, topic or intent classification.

Use the Actor through the API

Start a run and wait for the results with cURL:

curl -X POST "https://api.apify.com/v2/acts/automation-lab~facebook-public-post-keyword-search-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"searchQueries": ["coffee"], "maxPostsPerQuery": 20}'

JavaScript (npm install apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/facebook-public-post-keyword-search-scraper').call({
searchQueries: ['coffee', '#blackfriday'],
sortBy: 'recent',
maxPostsPerQuery: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]?.url);

Python (pip install apify-client):

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("automation-lab/facebook-public-post-keyword-search-scraper").call(
run_input={"searchQueries": ["coffee"], "sortBy": "top", "maxPostsPerQuery": 50}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["publishedAt"], item["authorName"], item["reactionsCount"], item["url"])

Use with AI agents through MCP

Connect the Actor to Claude, Cursor or another MCP client with the Apify MCP server. For Claude Code:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/facebook-public-post-keyword-search-scraper"

Claude Desktop: open Settings → Developer → Edit Config and add:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/facebook-public-post-keyword-search-scraper"
}
}
}

Cursor: add the same mcpServers block to ~/.cursor/mcp.json (or the project's .cursor/mcp.json).

VS Code: add the server to .vscode/mcp.json:

{
"servers": {
"apify": {
"type": "http",
"url": "https://mcp.apify.com?tools=automation-lab/facebook-public-post-keyword-search-scraper"
}
}
}

The Actor-specific URL also adds Apify's run and dataset helper tools. A safe agent workflow:

  1. Start once and keep the run ID. Use a small limit for chat answers, for example maxPostsPerQuery: 20 and maxItems: 50. A run of that size usually finishes in under a minute.
  2. Poll that same run with get-actor-run (waits of 2, 4, 8, then 10 seconds) with a total deadline of 3 minutes. If the deadline passes, do not start a new run: tell the user the run is still going, give the run ID, and check the same run again later. A second run would bill the same search twice.
  3. Read with a context budget. Call get-dataset-items with fields limited to what you need (for example url,text,publishedAt,reactionsCount,authorName) in pages of 20 rows, and stop at about 100 rows or 60 KB of UTF-8 text in total. Post texts can be long, so cut each text to about 300 characters in your answer.
  4. Say when the answer is partial. If the dataset has more rows than you read, say how many you used out of the total and give the dataset link (https://console.apify.com/storage/datasets/<datasetId>) or a CSV/JSON export URL (https://api.apify.com/v2/datasets/<datasetId>/items?format=csv) for the rest, instead of pasting everything into the chat.
  5. Check the status message of the finished run: it gives the posts delivered against the requested number and the stop reason for every query.

Example prompts:

  • "Find the 50 most recent public Facebook posts mentioning our brand and summarise the main complaints."
  • "Search Facebook posts for #blackfriday from the last 3 days and list the 10 with the most shares."
  • "Find public group posts asking for a plumber in the last week and give me the post links."

The Actor collects only public posts that Facebook shows to any signed-out visitor; it does not log in, bypass privacy settings or access private groups. Public posts can still contain personal data. You are responsible for using the data lawfully: follow GDPR, CCPA and other privacy laws, respect Facebook's terms where they apply to you, collect only what you need, and do not use the data for spam or harassment. If you are unsure, ask a lawyer. This Actor is not affiliated with or endorsed by Meta or Facebook.

When a run or a query fails, the Actor sends sanitized diagnostic data (the exception, your input with secret fields and URL query strings removed, and the Actor, build and run IDs) to our private GlitchTip error-tracking service so we can repair it. Reports are retained for 30 days.

FAQ

Do I need a Facebook account or cookies? No. The Actor uses Facebook's public post search as a signed-out visitor.

Why do some posts not contain my keyword? Facebook's search also returns related posts, for example posts whose author or attached content matches. Every row has matchesQuery; turn on mustContainQuery to keep only posts that contain every query word. Words are matched as parts of text, not as whole words, so car also matches Scarcity; use a longer or more specific word when that matters.

Why did I get fewer posts than I asked for? Facebook served no more result pages for that query, or your filters removed the rest. The status message shows the stop reason for every query. Try top instead of recent, a wider date window or broader keywords.

A query failed. What can I do? Facebook sometimes refuses a request; the Actor retries with fresh sessions. If Facebook keeps rate-limiting your proxy setting, the run switches to the default SHADER proxy, and the status message says so. Your own proxy URLs are never replaced, so if they are rate-limited, use the default proxy instead. If a query still fails, run it again later. If it keeps failing, open an issue on the Actor page with the run link.

Can I get the comments of each post? This Actor returns comment counts. Pass the post URLs to a Facebook comments scraper for the comment texts.

Can I search posts of one Page or group only? Use Facebook Pages Posts Scraper or Facebook Group Posts Scraper for that.