facebook-hashtag-search-scraper-top-posts-engagement-ranking avatar

facebook-hashtag-search-scraper-top-posts-engagement-ranking

Pricing

from $4.99 / 1,000 results

Go to Apify Store
facebook-hashtag-search-scraper-top-posts-engagement-ranking

facebook-hashtag-search-scraper-top-posts-engagement-ranking

Scrape Facebook hashtag search results — posts, reels, reactions, comments, shares, attachments and full Reels metadata. Built for speed and scale.

Pricing

from $4.99 / 1,000 results

Rating

0.0

(0)

Developer

SimpleAPI

SimpleAPI

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

4 hours ago

Last modified

Share

Facebook Hashtag Scraper — Posts, Reactions and Engagement Rank

Facebook Hashtag Scraper collects public posts from any Facebook hashtag feed and returns them as structured JSON — author, caption text, reaction breakdown, comment and share counts, video views and media attachments. Turn on engagement scoring and every post also gets a totalEngagement score, an engagementRank and a topReactionType, so the best-performing posts under a hashtag surface first instead of just the newest ones. It's built for social media analysts, brand and community managers, and researchers who need to know what's actually resonating under a tag, not just what was posted last.

What is Facebook Hashtag Scraper?

Facebook Hashtag Scraper is an Apify Actor that pulls the post feed behind one or more Facebook hashtags and shapes it into a typed dataset, with an optional scoring pass that ranks posts by engagement. Facebook only serves the hashtag feed to a logged-in session, so the Actor requires your own Facebook session cookie (c_user + xs, or the combined fbCookie string) — there is no anonymous or developer-account path into this feed.

  • Discovery by hashtag: plain tags (travel, #travel) or full hashtag URLs, any mix, in one run
  • Core identifying fields on every post: postId, user, url, text, time/timestamp
  • Secondary engagement data straight from Facebook: reaction breakdown, commentsCount, sharesCount, videoViewCount
  • Derived analytics when scoring is on: totalEngagement, engagementRate, topReactionType, engagementRank
  • Real filters: a minimum-engagement threshold and a newer-than date window (absolute date or relative window)
  • Download the dataset as JSON, JSONL, CSV, Excel, HTML table or XML, or read it straight through the Apify API

What data can I extract with Facebook Hashtag Scraper?

Every post is one dataset row carrying the base Facebook fields plus, when engagement scoring is on, seven derived analytics columns.

FieldExample ValueUse Case
searchQuery"streetfood"Which hashtag this row came from, when ranking several tags in one run
postId"1150692399746997"Facebook's post identifier
user{"name":"Jane Doe","id":"100012345678901","url":"https://www.facebook.com/profile.php?id=100012345678901","avatar":"https://scontent..."}Attribute the post to its author and link back to their profile
url"https://www.facebook.com/1150692399746997"Direct link to the post
text"Best tacos in town! #streetfood"Caption text for keyword/topic analysis
topReactions{"Like":120,"Love":34,"Haha":5}Per-reaction-type counts, Facebook's own labels
commentsCount42Comment volume
sharesCount12Share volume — the strongest virality signal
videoViewCount8500View count on video posts (0 on non-video posts)
time"2026-07-20 14:03:00"Post time as Facebook renders it (naive-local, not timezone-safe)
timestamp1753020180Unix seconds — the source of truth behind every date field
attachments[{"target":{"__typename":"Photo","id":"..."},"media":{...}}]Attached photos, videos, shares or albums with Facebook's own typed metadata
engagementRank1Position by totalEngagement among all posts collected for that hashtag (1 = highest)
totalEngagement178sum(topReactions) + commentsCount + sharesCount
engagementRate2.0941totalEngagement / videoViewCount * 100, video posts only
totalReactions159Sum of topReactions values
topReactionType"Like"The single most-used reaction on the post
passedEngagementFiltertrueWhether the post met minTotalEngagement — this also decides whether the row is billed
publishedAt"2026-07-20T14:03:00Z"UTC ISO-8601 timestamp, derived from timestamp — use this instead of time for any cross-timezone sorting

Engagement and reaction data

totalEngagement, engagementRate, topReactionType, engagementRank and passedEngagementFilter are all derived from data Facebook already returned on the post — no extra requests are made to compute them. topReactionType is simply whichever key in topReactions has the highest count; reaction names come through as Facebook's own localized labels (Like, Love, Haha, Wow, Sad, Angry, Care), not a fixed enum the Actor defines. engagementRate is set only when videoViewCount > 0 — for a non-video post there is no view denominator, so the field is null rather than a misleading 0. Turn computeEngagementScore off and all seven of these keys stay in the row, present but null, so the dataset shape never changes between runs.

Targeting and filtering data

onlyPostsNewerThan filters on the post's real timestamp, so it works whether you pass an absolute date or a relative window. minTotalEngagement filters on totalEngagement but does not drop anything below it — matching rows stay in the dataset flagged passedEngagementFilter=false, which is the field to threshold on downstream. searchQuery lets you segment a multi-hashtag run back out by tag before you do anything else with the rows.

Why not build this yourself?

Facebook does not publish a hashtag-search API for third parties — the Graph API covers content your own app or Page manages, not an arbitrary public hashtag feed, so there is no official endpoint to compare this Actor against.

Building it yourself means first reverse-engineering a moving target: the hashtag feed's GraphQL layer runs on persisted queries, so every session needs a fresh fb_dtsg token, an lsd token and the numeric doc_ids for SearchCometResultsInitialResultsQuery and SearchCometResultsPaginatedResultsQuery, all pulled out of the page's inline HTML and JS bundles rather than a documented request format. On top of that, Facebook ties a session's trust to its exit IP — replaying a cookie from a datacenter IP, or scattering one session's calls across many residential IPs, is what typically gets an account checkpoint-locked — and the feed silently serves a logged-out or checkpoint page instead of an error when a session is bad. Facebook Hashtag Scraper handles all of it: it extracts the session tokens per run, pins one sticky residential exit IP for the whole run and rotates only on a hard block, and detects the checkpoint/logged-out pages explicitly so a bad cookie fails fast with an actionable message instead of a silent empty result.

How to use data extracted from Facebook hashtag posts

  • 📊 Social media and brand teams run their brand or campaign hashtag through searchQueries, sort on totalEngagement, and pull the top engagementRank posts into a weekly report of what actually landed with the audience.
  • 🏢 Agencies running the same set of client and competitor hashtags on a schedule diff totalEngagement and topReactionType week over week to show clients whether sentiment and reach are trending up or down.
  • 🔬 Market researchers set onlyPostsNewerThan to a recent window and minTotalEngagement to a real-traction floor, then read text and topReactions across the surviving posts to map what a community is actually saying about a topic right now, not just what's loudest.
  • 🤖 AI agents and automated pipelines call the Actor as a standard Apify run, filter on passedEngagementFilter, and feed text plus the engagement fields into a summarizer or a trend-monitoring agent without any manual scoring step.

🔼 Input sample

Required: searchQueries.

ParameterRequiredTypeDescriptionExample Value
searchQueriesYesarrayOne or more Facebook hashtags to collect and rank. Plain tags (marketing, #travel) or full hashtag URLs (https://www.facebook.com/hashtag/travel) both work. Default ["football"].["fitness", "streetfood"]
maxItemsNointegerHow many posts to pull from each hashtag before scoring and ranking. Facebook's hashtag feed tops out around ~200 posts per tag. Minimum 1, maximum 10000, default 10.50
computeEngagementScoreNobooleanAdd the derived columns to every post: totalEngagement, engagementRate, topReactionType, engagementRank and publishedAt. Turn off to return raw posts only. Default true.true
sortByEngagementNobooleanOutput posts ordered highest-engagement first instead of Facebook's feed order. engagementRank is always filled regardless. Default true.true
minTotalEngagementNointegerOnly charge for posts whose totalEngagement is at least this value; lower-engagement posts are still returned but flagged passedEngagementFilter=false and are not billed. Minimum 0, default 0 (keep all).100
onlyPostsNewerThanNostringDrop posts older than this cutoff. Accepts an absolute date (2026-06-01) or a relative window (7 days, 2 weeks, 1 month). Leave empty to keep posts of any age."30 days"
fbCookieNostring (secret)Your Facebook session cookie as a single string, e.g. c_user=100012345678901; xs=34%3Aabcd.... Copy the c_user and xs values from DevTools → Application → Cookies → www.facebook.com. Kept secret; never stored. If set it fills c_user/xs below automatically."c_user=100012345678901; xs=34%3Aabcd..."
c_userNostringThe c_user Facebook cookie (your numeric user ID). Optional if you supplied the combined cookie string above."100012345678901"
xsNostring (secret)The xs Facebook cookie (URL-encoded session token). Optional if you supplied the combined cookie string above. Treated as a secret — it grants access to your account."34%3Aabcd1234..."
proxyConfigurationNoobjectBy default the actor pins a sticky residential IP (datacenter IPs are blocked by Facebook) and rotates on hard blocks. Override here to force your own proxy group. Default {"useApifyProxy": false}.{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}

Example input

{
"searchQueries": ["streetfood", "foodtruck"],
"maxItems": 100,
"computeEngagementScore": true,
"sortByEngagement": true,
"minTotalEngagement": 50,
"onlyPostsNewerThan": "30 days",
"fbCookie": "c_user=100012345678901; xs=34%3Aabcd...",
"proxyConfiguration": { "useApifyProxy": false }
}

Common pitfall: the Actor needs both c_user and xs — supplied directly or parsed out of fbCookie — or it cannot reach the feed at all. Explicit c_user/xs values always win over whatever fbCookie would have filled in. Without a working session, no hashtag is scraped: the run finishes successfully with a single, uncharged diagnostic row explaining that credentials are required, instead of failing or returning nothing with no explanation.

🔽 Output sample

⚠️ Facebook's hashtag feed itself tops out around ~200 posts per tag — raising maxItems past that will not pull more posts, because that ceiling is Facebook's, not the Actor's. Typed, normalized JSON, one row per post, same 19 keys every run. Export as JSON, CSV, Excel, HTML table or XML, or read the dataset through the Apify API.

Example output

{
"searchQuery": "streetfood",
"postId": "1150692399746997",
"user": {
"name": "Jane Doe",
"id": "100012345678901",
"url": "https://www.facebook.com/profile.php?id=100012345678901",
"avatar": "https://scontent.xx.fbcdn.net/v/t39.30808-1/avatar.jpg"
},
"url": "https://www.facebook.com/1150692399746997",
"text": "Best tacos in town! #streetfood",
"topReactions": { "Like": 120, "Love": 34, "Haha": 5 },
"commentsCount": 42,
"sharesCount": 12,
"videoViewCount": 8500,
"time": "2026-07-20 14:03:00",
"timestamp": 1753020180,
"attachments": [
{
"deduplication_key": "abc123",
"target": { "__typename": "Photo", "id": "1150688623080708" },
"__typename": "StoryAttachment",
"style_list": ["photo", "fallback"],
"styles": {},
"media": {},
"all_subattachments": { "nodes": [] }
}
],
"engagementRank": 1,
"totalEngagement": 178,
"engagementRate": 2.0941,
"totalReactions": 159,
"topReactionType": "Like",
"passedEngagementFilter": true,
"publishedAt": "2026-07-20T14:03:00Z"
}

If a hashtag yields zero posts — an unusual tag, expired cookies, a locked account, or a transient Facebook block — the run still finishes successfully with one diagnostic row (fields status and message in place of the usual data) instead of failing, and that row is never charged.

How do you filter and target specific posts?

Two axes decide what lands in your dataset: how much you collect, and what counts as worth keeping. maxItems sets how many posts are pulled per hashtag before scoring — but Facebook's own feed ceiling of roughly 200 posts per tag caps this in practice regardless of how high you set it, so raising it past that point buys nothing. onlyPostsNewerThan narrows by time, accepting either an absolute date or a relative window like 7 days or 2 weeks — posts with no readable timestamp are kept rather than dropped, so a parsing gap never silently loses data. minTotalEngagement is the quality threshold, but it's an accounting filter, not a drop filter: posts below it stay in the dataset with passedEngagementFilter=false and are simply not billed, so you can audit what got filtered without paying for it. To isolate only the rows Facebook actually charged you for, filter on passedEngagementFilter !== false (equivalent to === true here, since the field is only ever null when computeEngagementScore is off, in which case every row is charged).

{ "searchQueries": ["marketing"], "maxItems": 200, "onlyPostsNewerThan": "7 days" }
{ "searchQueries": ["fitness"], "minTotalEngagement": 500, "sortByEngagement": true }
{ "searchQueries": ["travel", "wanderlust"], "onlyPostsNewerThan": "2026-06-01", "computeEngagementScore": true }

▶️ Want to try other Facebook scrapers?

Scraper NameWhat it extracts
Facebook Search Scraper by HashtagPages posting under a hashtag, plus each Page's full profile
Facebook Group Engagement AnalyzerRanks a Facebook Group's own posts by engagement score
Facebook Page Content Strategy ScraperA Page's content-type mix, hashtags, mentions and CTAs
Facebook Pages Scraper with Ad Library ActivityPublic Pages plus their live Ad Library activity
Instagram Reels Hashtag ScraperInstagram Reels by hashtag with engagement ranking
TikTok Trending Hashtags ScraperTikTok trending hashtags with daily growth history

How to extract Facebook hashtag data programmatically

Facebook Hashtag Scraper runs as a standard Apify Actor — one authenticated call through the Apify API, structured JSON back, no scraping infrastructure of your own to run.

Python example

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("<YOUR_USERNAME>/facebook-hashtag-search-scraper-top-posts-engagement-ranking").call(run_input={
"searchQueries": ["streetfood"],
"maxItems": 100,
"minTotalEngagement": 50,
"fbCookie": "c_user=100012345678901; xs=34%3Aabcd...",
})
for post in client.dataset(run["defaultDatasetId"]).iterate_items():
if post.get("passedEngagementFilter") is not False:
print(post["text"][:60], post["totalEngagement"], post["topReactionType"])

Works in Go, Ruby, Node.js, cURL — any language that can make an HTTP request.

Export to spreadsheets or CRM

Download the dataset as CSV directly from the Apify Console, or pull it through the API and map text, totalEngagement, engagementRank and url into a spreadsheet or CRM import — user.name and user.url map cleanly to a contact/author column for lead or influencer tracking.

Scraping content that a logged-in visitor can already see on Facebook's own hashtag feed is generally treated as accessing published content, not breaching a technical barrier — this Actor surfaces only what that feed already shows to a signed-in session, nothing behind a private group or friends-only wall.

Hashtag posts are personal data in the general sense: captions, reactions and profile links are attributed to whoever posted, whether an individual profile or a business Page, so GDPR and CCPA framing applies to any storage or reuse of the collected rows — you need a lawful basis to retain and process personal data pulled this way, and should minimize what you keep to what your use case actually needs.

Consult legal counsel for commercial applications involving bulk storage of personal data.

❓ Frequently asked questions

What if a hashtag has zero recent posts?

The run still finishes successfully. Instead of an empty or failed run, the Actor pushes one uncharged diagnostic row explaining why — an unusual or empty hashtag, a transient Facebook block, or invalid credentials — so you always know why the dataset is empty rather than having to guess.

Can I get engagement data along with the posts?

Yes, and it's on by default. computeEngagementScore=true adds totalEngagement, engagementRate, topReactionType, engagementRank and publishedAt to every post at no extra request — all derived from fields Facebook already returned in the same response.

How accurate is the engagement data?

The Actor returns reaction, comment and share counts exactly as Facebook's feed reports them at request time. Accuracy depends on Facebook's own count at that moment, which can keep climbing after you scrape it — re-run periodically if you need current numbers rather than a one-time snapshot.

How many posts can I get per run?

maxItems accepts 1 to 10,000, but Facebook's hashtag feed itself tops out around ~200 posts per tag regardless of what you set — that ceiling belongs to Facebook, not the Actor, so there's no value in setting maxItems far above it for a single hashtag.

How does the minimum-engagement filter actually work?

minTotalEngagement doesn't drop low-engagement posts — it flags them. Posts below your threshold still appear in the dataset with passedEngagementFilter=false, but they're excluded from billing rather than from the output, so you can see everything Facebook returned while only paying for the posts that cleared your bar.

Does Facebook Hashtag Scraper work with Claude, ChatGPT and other AI agent frameworks?

Yes. It is callable as a standard HTTP endpoint through the Apify API, so any agent framework that can make a request — LangChain, CrewAI, n8n, a custom tool definition — can invoke it and receive typed JSON directly.

How does Facebook Hashtag Scraper compare to other Facebook post scrapers?

Checked on the Apify Store as observed on 2026-07-26: scraper_one/facebook-posts-search documents keyword and location search returning post URL, reactions, comments and shares, with no engagement scoring or ranking documented. easyapi/facebook-posts-search-scraper documents a similar keyword-search field set (likes, comments, shares) with no ranking or filtering beyond a result-count cap. scrapeforge/facebook-search-posts documents the broadest search surface — six content types including posts, pages and videos — but ranking, engagement scoring and an uncharged-row filter mechanic are not documented on any of the three. Facebook Hashtag Scraper's difference is scoring and ranking the posts it collects — totalEngagement, engagementRank, topReactionType — and a minTotalEngagement threshold that keeps low-performing posts visible without billing for them.

Can I use Facebook Hashtag Scraper without a Facebook API key or developer account?

Yes — and you have to, since there is no Facebook developer API for the hashtag feed to authenticate against. What you supply instead is your own Facebook session: the c_user and xs cookie values from a logged-in browser session (directly, or combined in fbCookie), which the Actor uses only to request the feed and never persists in the dataset.

Conclusion

Facebook Hashtag Scraper turns any Facebook hashtag feed into a ranked, structured dataset — posts scored on totalEngagement, ordered by engagementRank, and filterable by a real minimum-engagement threshold that never bills for the rows it excludes. It's built for social teams, agencies and researchers who need to find what's actually working under a hashtag, not just what's newest. Open Facebook Hashtag Scraper on Apify, supply your Facebook session cookie and a hashtag, and start the run.