Facebook Search Scraper By Hashtag
Pricing
from $2.99 / 1,000 results
Facebook Search Scraper By Hashtag
Extract public Facebook search results fast with Facebook Search Scraper. Collect profiles, pages, groups, posts, and related data using targeted keywords. Perfect for lead generation, competitor analysis, and market research with clean, structured export options.
Pricing
from $2.99 / 1,000 results
Rating
0.0
(0)
Developer
SimpleAPI
Maintained by CommunityActor stats
0
Bookmarked
33
Total users
8
Monthly active users
4 days ago
Last modified
Categories
Share
Facebook Hashtag Scraper — Pages, Posts and Contact Data
Facebook Search Scraper By Hashtag takes a hashtag instead of a page URL and returns every Facebook Page it can find posting under that tag — as one row per Page, carrying the matching post (text, date, reactions, comments, shares) plus the Page's full public business profile: category, address, phone, email, website, rating, hours and linked accounts. Two independent discovery channels feed it: the live hashtag feed and a web-index search. Built for social listening teams, agencies auditing hashtag campaigns, and researchers mapping who is actually using a tag right now — no Facebook login required.
What is Facebook Search Scraper By Hashtag?
It is an Apify Actor that starts from a hashtag (or a category and location) and works backwards to the Facebook Pages behind it, returning a business-page record for each one it finds. It runs fully logged out — no Facebook account, cookie or session token is required for any of the three discovery paths it uses.
Key capabilities:
- Two ways to discover Pages by hashtag — reading
facebook.com/hashtag/<tag>directly for live posts, and searching the web index for"#tag" site:facebook.comto recover Pages from indexed post permalinks. - A classic category × location channel — the same
Pub+NYC-style business search other Facebook scrapers offer, runnable alongside or instead of the hashtag channels. - The full business profile on every row — address, phone, email, website, rating, hours, price tier and linked social accounts, not just the post that matched.
- A hashtag-match block attached to each Page — post text, timestamp, reaction count, top reaction types, comment count, share count, video views and attached media, when the post came from the live feed.
- A match filter (
onlyPagesWithMatch) to keep only Pages with real hashtag evidence, or to widen the run to plain category/location results too. - Live streaming JSON output, exportable as JSON, CSV, Excel, XML or HTML, or read straight from the Apify API.
What data can I extract with Facebook Search Scraper By Hashtag?
Every row combines two kinds of data: identity and contact details for the Page itself, and — when a hashtag produced the row — the post that tied it to that tag.
| Field | Example value | Use case |
|---|---|---|
facebookUrl / pageUrl | https://www.facebook.com/FortMyersFarmersMarket | Canonical link back to the Page |
title / pageName | Fort Myers Farmers Market | Display name / URL slug |
pageId / facebookId | 100064123456789 | Stable Page identifier |
categories / category | ["Farmers Market"] / Farmers Market | Business type |
address / addressUrl | Fort Myers, FL | Location and a map link |
phone | +1 239-691-9249 | Contact for outreach |
email | market@example.com | Contact for outreach |
website / websites | example.com | Off-platform link |
rating / ratingOverall / ratingCount | 92% recommend (146 Reviews) | Trust signal |
followers / followersLabel / followersIsApproximate | 5300 / "5.3K" / true | Audience size |
business_hours | Open now | Availability |
business_price / priceRange / priceRangeRaw / priceTier | $$ / 2 | Price positioning |
instagram / alternativeSocialMedia / linkedAccounts / externalLinks | [{"username":"fmfarmersmkt","url":"..."}] | Cross-platform reach |
profilePictureUrl / coverPhotoUrl / profilePhoto | image URL | Visual identity |
intro / about_me / info / likes | text / array | Page description |
creation_date / ad_status / pageAdLibrary | text / object | Page age and ad activity, when published |
hashtagMatch | object (below) | The post that matched the hashtag |
matchedHashtags / hashtagPostCount | ["#shoplocal"] / 1 | Which tag matched, and whether a live post backs it |
discoverySource / discoveryQuery | hashtag_feed / #shoplocal | Which channel found this Page and with what query |
pageStatus | ok | Row health flag |
Hashtag match and engagement fields
hashtagMatch is a nested object carrying everything Facebook exposes about the specific post that connected a Page to a hashtag: hashtag, foundOn (hashtag_feed or hashtag_web_search), postId, postUrl, postText, postCreatedAt (UTC ISO-8601), postCreatedTimestamp (Unix seconds), matchedTerms, postedByName / postedById / postedByUrl, mediaType, attachedMediaUrl, attachedMediaCount, reactionCount, topReactions (up to 3 {type, count} entries), commentCount, shareCount, shareCountLabel, videoViewCount and matchStatus. Only the hashtag-feed channel (readHashtagFeed) populates the engagement numbers — reactions, comments, shares and post text are never available from the web-index channel, which only confirms that a post exists.
Discovery and targeting fields
discoverySource tells you which of the three channels produced the row (hashtag_feed, hashtag_web_search, category_search); discoveryQuery records the exact tag or category+location query that found it. matchStatus inside hashtagMatch is one of matched (live post confirmed), web_reference (indexed permalink only, no engagement data), no_match, or page_url_unavailable. categories and locations on the input side are what you filter the base channel by; onlyPagesWithMatch filters the output by whether hashtag evidence exists at all.
Why not build this yourself?
Facebook does not publish a public hashtag-search or business-search API for third parties — there is no official endpoint that returns "Pages posting under #tag" or "Pubs in NYC" to an anonymous or app-registered caller. Its own logged-out /search/… endpoints return nothing usable without a session.
Building this from scratch means solving three separate problems at once: locating the Relay JSON blob Facebook hydrates into facebook.com/hashtag/<tag> (which renders exactly one post per load, with no pagination and no exposed cursor query id); recovering the owning business Page from a bare post permalink returned by a web search, while correctly discarding groups, personal profiles and numeric-id profiles that all 400 when fetched logged out; and running a proxy escalation ladder — datacenter, then residential — that only engages when a response is genuinely blocked rather than false-triggering on ordinary page content. Each of those took specific, measured fixes to get right (documented below); getting all three working together before writing a single row of output is the real cost of doing it yourself.
How to use data extracted from Facebook Search Scraper By Hashtag?
Social listening and brand monitoring teams
Point hashtags at your branded tag or a campaign tag (#shoplocal, your product name) with readHashtagFeed on, and every matching Page arrives with hashtagMatch.reactionCount, commentCount and shareCount already attached, plus that Page's phone and email for direct follow-up with your best-performing UGC creators.
Agencies auditing hashtag campaigns
Run the same hashtag set on a schedule across a client roster and compare hashtagPostCount and discoverySource per run to see whether a campaign tag is picking up new Pages or plateauing, without re-building a hashtag-to-Page lookup each time.
Market research and competitive intelligence
Combine categories and locations with alsoSearchWeb to see which businesses in a category and city are also posting under a given tag — cross-referencing category, address and hashtagMatch.hashtag shows where a trend and a market segment overlap.
AI agents and automated pipelines
Because every row is typed JSON with a stable 50-key schema, an agent can call this Actor as a tool, filter on matchStatus == "matched" for confirmed live activity, and feed postText, title and address straight into a summarization or lead-scoring pipeline without a parsing step.
⬇️ Input
No parameter is required — every field has a default, so the Actor runs as-is with the store's demo hashtag and category.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
categories | No | array | Business types to search (Pub, Bar, Restaurant...). Combined with locations → e.g. "Pub NYC", "Bar London". Optional secondary channel — leave as-is if you only want hashtags. Default ["Pub"]. | ["Pub", "Coffee Shop"] |
locations | No | array | Where to search (NYC, London...) — paired with each category. Default ["NYC"]. | ["NYC", "London"] |
resultsLimit | No | integer | Max pages to scrape across all queries. Higher = more data, longer run. Minimum 1, maximum 500. Default 10. | 20 |
proxyConfiguration | No | object | Optional. No proxy by default. Auto fallback to datacenter → residential if blocked. If you leave this off, the hashtag feed still rotates residential sessions on its own — that rotation is the only way to see more than one post per tag. | {"useApifyProxy": false} |
hashtags | No | array | Hashtags to search, with or without the leading #. Each one is read from facebook.com/hashtag/<tag> and from the web index. Default ["#shoplocal"]. | ["#shoplocal", "#smallbusiness"] |
readHashtagFeed | No | boolean | Read facebook.com/hashtag/<tag> directly. This is the only channel that returns live reactions, comments, shares and the post text. Default true. | true |
hashtagFetchesPerTag | No | integer | How many times to load each hashtag page, each through a fresh proxy exit. The page renders one post per load and the same exit replays the same cached post, so this is the only breadth lever. Measured on #shoplocal: 6 rotating residential sessions returned 5 distinct posts. Minimum 1, maximum 10. Default 4. | 6 |
alsoSearchWeb | No | boolean | Adds a second channel: "#tag" site:facebook.com. Post permalinks are converted back to their owning Page; groups, personal profiles and numeric-id profiles are filtered out. Default true. | true |
maxPagesPerHashtag | No | integer | Cap on how many pages the web-index channel may contribute for each hashtag. Minimum 1, maximum 200. Default 20. | 20 |
onlyPagesWithMatch | No | boolean | Keep only pages with hashtag evidence — a live post from the feed, or an indexed post permalink. Turn off to also keep category × location results that never used the tag. Ignored when no hashtag is supplied. Default true. | true |
cookies | No | object (secret) | Optional cookie jar as a JSON object, e.g. {"c_user": "...", "xs": "..."}. Everything this actor scrapes was verified logged out, so leave this empty. Provided only so the field is declared rather than silently read. | {} |
Example input
{"hashtags": ["#shoplocal", "#smallbusiness"],"readHashtagFeed": true,"hashtagFetchesPerTag": 6,"alsoSearchWeb": true,"maxPagesPerHashtag": 20,"onlyPagesWithMatch": true,"categories": [],"locations": [],"resultsLimit": 30,"proxyConfiguration": { "useApifyProxy": false }}
Common pitfall: hashtags defaults to ["#shoplocal"] and categories defaults to ["Pub"] — both channels run together out of the box. If you only want plain category-and-location business discovery with no hashtag involved, clear hashtags to an empty array; otherwise the hashtag channels keep running against the default tag alongside your category search.
⬆️ Output
One dataset row per Facebook Page, live-streamed as each Page is scraped. The Actor's console dataset view surfaces 12 columns by default — facebookUrl, title, hashtagMatch, discoverySource, categories, address, phone, email, website, rating, followers, profilePictureUrl — plus an alternate Hashtag matches only view with facebookUrl, title, hashtagMatch, matchedHashtags, hashtagPostCount, discoverySource. Both are a subset: a successfully scraped row carries 50 top-level keys in full.
A page that comes back login-walled, blocked or unparseable is not written as a null-filled row of those 50 keys. It is pushed as a separate, minimal, uncharged accounting item — only facebookUrl, error, errorReason, discoverySource, discoveryQuery and hashtag are present, and every other field is omitted entirely rather than set to null. Filter these out of a clean dataset with !item.error (or, on a successful row, item.pageStatus === "ok").
Export as JSON, CSV, Excel, XML or HTML, or read the dataset through the Apify API.
Example output
{"facebookUrl": "https://www.facebook.com/FortMyersFarmersMarket","categories": ["Farmers Market"],"info": ["Fort Myers Farmers Market"],"likes": 5100,"messenger": null,"priceRange": "$$","title": "Fort Myers Farmers Market","address": "Fort Myers, FL","pageId": "100064123456789","pageName": "FortMyersFarmersMarket","pageUrl": "https://www.facebook.com/FortMyersFarmersMarket","intro": "Weekly farmers market in downtown Fort Myers","websites": ["https://fortmyersfarmersmarket.com"],"phone": "+1 239-691-9249","email": "market@fortmyersfarmersmarket.com","alternativeSocialMedia": "https://instagram.com/fmfarmersmkt","website": "fortmyersfarmersmarket.com","services": null,"rating": "92% recommend (146 Reviews)","followers": 5300,"followings": 210,"profilePictureUrl": "https://scontent.fbcdn.net/profile.jpg","coverPhotoUrl": "https://scontent.fbcdn.net/cover.jpg","profilePhoto": "https://www.facebook.com/photo/?fbid=100064123456789","ratingOverall": 92,"ratingCount": 146,"category": "Farmers Market","addressUrl": "https://www.bing.com/maps/default.aspx?...","instagram": [{ "username": "fmfarmersmkt", "url": "https://instagram.com/fmfarmersmkt" }],"ratings": "92% recommend (146 Reviews)","business_hours": "Open now","business_price": "Price Range · $$","business_services": null,"creation_date": "March 12, 2014","ad_status": null,"about_me": { "text": "Weekly farmers market in downtown Fort Myers" },"facebookId": "100064123456789","pageAdLibrary": { "is_business_page_active": null, "id": null },"hashtagMatch": {"hashtag": "#shoplocal","foundOn": "hashtag_feed","postId": "26930704839940052","postUrl": "https://www.facebook.com/FortMyersFarmersMarket/posts/26930704839940052","postText": "Come shop local with us this Saturday! #shoplocal #farmersmarket","postCreatedAt": "2026-07-09T12:11:49Z","postCreatedTimestamp": 1783771909,"matchedTerms": [],"postedByName": "Fort Myers Farmers Market","postedById": "100064123456789","postedByUrl": "https://www.facebook.com/FortMyersFarmersMarket","mediaType": "photo","attachedMediaUrl": "https://scontent.fbcdn.net/photo.jpg","attachedMediaCount": 1,"reactionCount": 42,"topReactions": [{ "type": "Like", "count": 38 }, { "type": "Love", "count": 4 }],"commentCount": 6,"shareCount": 3,"shareCountLabel": "3","videoViewCount": null,"matchStatus": "matched"},"matchedHashtags": ["#shoplocal"],"hashtagPostCount": 1,"discoverySource": "hashtag_feed","discoveryQuery": "#shoplocal","pageStatus": "ok","priceRangeRaw": "Price range · $$","priceTier": 2,"followersLabel": "5.3K","followersIsApproximate": true,"linkedAccounts": { "instagram": "https://instagram.com/fmfarmersmkt" },"externalLinks": ["https://instagram.com/fmfarmersmkt"]}
How do you filter and target specific Pages?
Two independent channels do the actual discovery, and they work differently. The hashtag feed (hashtags + readHashtagFeed) reads facebook.com/hashtag/<tag> directly — it is the only source of live reactions, comments, shares and post text, but the page renders exactly one post per load with no pagination, so hashtagFetchesPerTag (each fetch through a fresh proxy exit) is the only way to surface more than one post per tag. The web-index channel (alsoSearchWeb + maxPagesPerHashtag) searches "#tag" site:facebook.com and recovers the owning Page from indexed post permalinks — it finds more Pages but never carries engagement numbers, only confirmation that a post exists (matchStatus: "web_reference"). If a Page is discovered by both, the hashtag-feed's richer record wins and the web-index sighting for that same Page is dropped rather than merged.
Layer the classic categories × locations channel on top for plain business discovery, then use onlyPagesWithMatch as your quality gate: true (the default) keeps only Pages with confirmed hashtag evidence — a live post or an indexed permalink — and drops everything else, including category/location results that never touched the tag; false keeps all of it. resultsLimit caps the total rows across every channel in one run.
{ "hashtags": ["#shoplocal"], "readHashtagFeed": true, "hashtagFetchesPerTag": 8, "alsoSearchWeb": false }
{ "hashtags": ["#coffeeroasters"], "alsoSearchWeb": true, "maxPagesPerHashtag": 50, "onlyPagesWithMatch": true }
{ "categories": ["Coffee Shop"], "locations": ["Seattle"], "hashtags": [], "onlyPagesWithMatch": false, "resultsLimit": 50 }
How does Facebook Search Scraper By Hashtag handle proxies and blocking?
Proxy behavior differs by channel, and by design. On the hashtag feed, session rotation is the whole strategy: if you supply your own proxy it is tried first, otherwise the Actor automatically requests an Apify Residential proxy (falling back to Datacenter) for that channel regardless of whether you configured one — this is what "rotates residential sessions on its own" means. With no proxy available at all, every fetch reuses the same exit IP, and Facebook replays the same cached post, so breadth drops to one post per tag. On the page-scrape step, a block triggers an independent escalation ladder — Datacenter, then Residential — up to three attempts, using Apify's own proxy groups regardless of your proxyConfiguration. The category/location channel requires Apify's GOOGLE_SERP proxy group to run at all; if it is unavailable, that channel is skipped with a log warning rather than failing the run.
Blocking itself is classified narrowly: a response only counts as blocked on HTTP 403/429/503, on landing at /login, or on a body under 120,000 bytes with no Relay result container — not on loose text matches, which the source notes previously misclassified genuine pages as blocked.
How to extract Facebook data programmatically
Python example
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("<YOUR_USERNAME>/facebook-search-scraper-by-hashtag").call(run_input={"hashtags": ["#shoplocal"],"hashtagFetchesPerTag": 6,"alsoSearchWeb": True,"onlyPagesWithMatch": True,})for page in client.dataset(run["defaultDatasetId"]).iterate_items():if page.get("pageStatus") == "ok":print(page["title"], page["phone"], page["hashtagMatch"]["reactionCount"])
Export to spreadsheets or CRM
Export the dataset as CSV directly from the Apify Console or API, and map title, phone, email, address and website straight into CRM contact columns, with hashtagMatch.postUrl and hashtagMatch.reactionCount kept as reference fields for the campaign context.
Is it legal to scrape Facebook business Pages?
Scraping publicly visible Facebook Page data is generally permissible where no login or authentication is bypassed, and this Actor reads only content Facebook already serves to a logged-out visitor. A Facebook Page is a business record by nature — its category, address, phone, hours and rating exist so the public can find and contact the business, and this Actor collects nothing behind a login wall or a private group.
The attached hashtagMatch post is incidental content layered onto that business record: it may be authored by the Page itself or, less often, reshared or tagged by an individual poster. Because the primary entity here is the business Page, the applicable framework is Facebook's terms of service and database-rights considerations around systematic reuse of a compiled dataset, rather than GDPR-style personal-data rules — though if a matched post's author is an individual rather than a Page, treat that specific record with the same care you would any personal data.
Consult legal counsel for commercial applications involving bulk storage of this data.
❓ Frequently asked questions
What if a hashtag or category+location combo returns zero matching Pages?
The run does not fail or fabricate a row. Some hashtags serve an empty page shell logged out with zero posts (the source notes this measured on #fitness and #pubnyc), which surfaces as no candidates from that channel; a category+location combo with no results simply contributes nothing. Widen the hashtag, try a related tag, or turn onlyPagesWithMatch off to keep category/location results even without a match.
Can I get the post's engagement numbers along with the Page data?
Yes, but only from the hashtag-feed channel. When readHashtagFeed is on and a post is found, hashtagMatch carries reactionCount, topReactions, commentCount, shareCount and videoViewCount alongside the full Page profile. The web-index channel only confirms a post exists (matchStatus: "web_reference") — it never carries these numbers.
How accurate is the contact and rating data?
The Actor returns data exactly as it appears on the Page's public profile at request time. Accuracy depends on whether the business keeps its own Facebook listing current — a stale hours field or old phone number is the Page owner's data, reproduced faithfully. Verify contact details before using them in outreach at scale.
How many Pages can I get per run?
resultsLimit caps the total across every channel, from 1 to 500, defaulting to 10. The category channel additionally splits its own budget (resultsLimit divided roughly three ways) when hashtags are also active, so the hashtag channels get the larger share of the cap.
Why doesn't raising hashtagFetchesPerTag guarantee more posts?
Because the yield is measured, not fixed. On #shoplocal, 6 rotating residential sessions returned 5 distinct posts — a good ratio, but every fetch depends on which post a fresh proxy exit happens to be served, so the same setting can return fewer distinct posts on a quieter tag. Raising the value improves the odds; it does not guarantee a specific count.
Am I charged for Pages that fail to scrape?
No. A login-walled, blocked or unparseable Page is pushed as an uncharged accounting row with only facebookUrl, error, errorReason, discoverySource, discoveryQuery and hashtag — no charge is applied, and the row is easy to exclude by filtering on the presence of error.
Does Facebook Search Scraper By Hashtag work with Claude, ChatGPT and other AI agent frameworks?
Yes. It is callable as a standard HTTP endpoint through the Apify API, so LangChain, CrewAI, n8n or a hand-written tool definition can invoke it and receive typed JSON with no parsing step.
How does Facebook Search Scraper By Hashtag compare to other Facebook hashtag scrapers?
Checked on the Apify Store on 2026-07-26: easyapi/facebook-hashtag-search-scraper documents a single required searchQuery input and returns one row per post with a nested user object (name, ID, URL, avatar) — post-level data only, no business-profile enrichment. datapilot/facebook-hashtag-search-scraper documents the same post-and-user output shape and recommends (rather than requires) a residential proxy; its published example output is explicitly sample data rather than a live scrape. scrapium/facebook-hashtag-search-scraper documents c_user and xs Facebook cookies as required inputs, stating plainly that "Facebook's hashtag search results are only returned to authenticated sessions" for its approach. None of the three documents resolving a post back to the owning Facebook Page's business profile — contact info, address, rating or hours — which is this Actor's output on every row, and none requires a login cookie, since every surface this Actor reads was verified reachable logged out.
Can I use Facebook Search Scraper By Hashtag without a Facebook account or login?
Yes. No Facebook account, cookie or session is required for any of the three discovery channels. The cookies input exists only so the field is declared rather than silently read — leave it empty.
🔗 Related scrapers
| Scraper Name | What it extracts |
|---|---|
| Facebook Hashtag Search Scraper Top Posts Engagement Ranking | Hashtag posts ranked by engagement, without the Page-profile chaining this Actor adds |
| Facebook Pages Scraper With Ad Library Activity | Business Page profiles enriched with ad-library activity, without hashtag discovery |
| Facebook Page Content Strategy Scraper | A Page's own post history and content patterns |
| Facebook Video Search Scraper Description Hashtags | Video posts discovered by hashtags in their description |
| Facebook Groups Search Scraper Size Activity Report | Group discovery and activity, for the group surface this Actor deliberately excludes |
| Instagram Reels Hashtag Scraper | The equivalent hashtag-to-post discovery flow on Instagram |
💬 Your feedback
Found a bug, or need a field that Facebook exposes but this Actor doesn't return yet? Open an issue on the Actor's Issues tab — reports that include the hashtag or category/location combo you ran are the fastest to reproduce and fix.
