Facebook Event Search Scraper By City, Topic & Venue avatar

Facebook Event Search Scraper By City, Topic & Venue

Pricing

from $1.55 / 1,000 results

Go to Apify Store
Facebook Event Search Scraper By City, Topic & Venue

Facebook Event Search Scraper By City, Topic & Venue

Facebook Event Search Scraper discovers public events by city, topic, and venue. Extract event names, dates, locations, hosts, descriptions, ticket links, categories, and related details for event research, local discovery, promotion, and market analysis.

Pricing

from $1.55 / 1,000 results

Rating

0.0

(0)

Developer

Scrapio

Scrapio

Maintained by Community

Actor stats

0

Bookmarked

4

Total users

1

Monthly active users

20 hours ago

Last modified

Share

Facebook Event Scraper — Extract Events, Venues and City Coverage

Search public Facebook events across a list of cities and topics, and get back three typed row kinds in one dataset: one row per event, one coverage row per topic-and-city search (including cities that genuinely returned nothing), and one roll-up row per venue. This Facebook event scraper runs a separate search for every topic-city pair, attributes each event to the city that surfaced it, resolves the venue behind it, and reports the outcome honestly — including the searches that found nothing and the ones that could not be answered. No login, cookies, or Facebook developer account required. Unlike scraping frameworks that return raw HTML, it returns typed JSON, ready for a database, a spreadsheet, or an LLM context window without any parsing. The guide below covers every input, every output field, and how teams run it for local event monitoring, venue lead generation, and RAG pipelines.

🧭 What Does Facebook Event Scraper Do?

Facebook Event Search Scraper By City, Topic & Venue fans a topic list out across a city list — every topic is searched once per city — and reads the results straight from Facebook's public events search, no account or login required. It returns three related entity types: event records (title, ID, URL, venue, city attribution), city coverage records (what happened when a topic was searched in a given city, including a genuine zero), and venue roll-ups (how many events at that venue, in which cities, with combined interest). Nothing is inferred across cards — every field comes from the same event's own data, and an absent value is reported as null, never guessed or zeroed.

  • City fan-out — every topic is searched once against every city; 2 topics × 3 cities runs 6 searches
  • Honest city attribution — every event row states whether the requested city actually appears in the venue text, and how confident that attribution is
  • A coverage row per search — one row per topic-city pair, including searches that found nothing and searches that returned no usable answer at all
  • Venue resolution — venue name, venue ID, venue kind, and a venue page link where the venue is a real Facebook Page
  • Venue roll-up — one summary row per distinct venue: event count, which cities it appeared under, combined "interested" figure
  • Deep pagination — each search keeps following the results feed instead of stopping at the first page
  • Legacy-input compatible — the original actor's startUrls and maxEvents keys still work unchanged

⚡ Features & Capabilities

Everything below is grouped by what it does for the data you get out, not by marketing category.

Core features

  • Structured event fields straight from Facebook's own search response: event_id, title, url, venueName, venuePlaceId, venuePlaceType, venuePageUrl
  • City attribution on every event row: matchedCity, venueCityMatch, cityMatchConfidence
  • Deduplication across cities — an event surfaced by two different city searches is saved once, and the overlap is reported (duplicateEventsSkipped, duplicateWithCities) on the later city's coverage row, not silently dropped
  • A dedicated searchStatus value for every search outcome — ok, no_results, no_city_match, unavailable — so an empty city and a broken search are never the same thing
  • Venue rows are also mirrored into a separate <runId>-venues dataset for the run, in addition to the main dataset
  • Output as typed JSON, exportable from the Apify platform to CSV, Excel, XML, RSS, or accessed directly via the Dataset API

When another tool might suit you better

If you need Facebook Events data scoped to a single known Page's own event calendar rather than a keyword-and-city search, a Page-events scraper that reads one Page's event list directly will get you there with fewer searches than fanning a topic out across cities. This actor is built for open-ended discovery — "what comedy is happening in London" — not for monitoring one organizer's existing calendar.

Facebook Event Search Scraper within the Scrapio data stack

Facebook Event Search Scraper By City, Topic & Venue covers Facebook events. For Facebook reviews, use ../../Facebook-Reviews-Scraper/facebook-reviews-scraper-with-date-and-keyword-filters. For Facebook video transcripts, use ../../Facebook-Video-Transcript-Extractor/facebook-video-transcript-with-caption-extractor. Each covers a distinct Facebook entity type and can be run independently or chained into the same pipeline.

Why do developers and data teams scrape Facebook events?

🏢 Local marketing and events teams

An agency running comedy nights, live music, or meetups in several cities feeds cities and searchTopics in, gets back one row per event with venueName and venuePageUrl, and can immediately see which venues in each city already host that kind of event — a warm outreach list, not a cold one. The venue roll-up rows turn a flat event list into a ranked venue target list without any extra processing, sorted by eventCountInRun.

📊 AI training data and RAG indexing

title, venueName, and searchTopic are the high-information text fields worth indexing for a RAG store of local happenings — a query like "comedy clubs in London" resolves against exactly those fields. For training data, searchStatus, venueCityMatch, and cityMatchConfidence are the fields with the most consistent structure across every row, since they are enums rather than free text. Both use cases benefit from the fact that every field returns as a typed primitive — string, boolean, or number — with no HTML to strip first.

📱 Competitive and market intelligence

Running the same searchTopics list across a fixed set of cities on a schedule turns eventsFound and cityHitRatePct into a week-over-week signal for how active a scene is in each city — useful for a ticketing company or venue aggregator deciding where to expand next, without touching a single event page by hand.

🔬 Research and academic use

Urban studies, sociology, and cultural-events research can use the city coverage rows as a public-data census of what kind of events are being publicly promoted in a city, topic by topic. This actor reads only what Facebook's public events search already serves to a logged-out visitor — no private groups, no private events, no follower-only content.

🎥 Product and SaaS development

A local-events directory, a "what's on" newsletter, or a venue-discovery app can run this actor on a schedule and treat the dataset as its ingestion feed: event rows populate the listing, venue rows populate a venue directory, and scrapedAt gives every row a freshness timestamp.

🍚 Input Parameters

All fields are optional per the schema (required: []), but the run needs at least one topic — from searchTopics or the legacy startUrls — or it fails with "No search topics were provided."

ParameterRequiredTypeConstraintsDescriptionExample
citiesNoarray (stringList)One city per line, e.g. "London", "Berlin", "New York". Every topic is searched once per city. City names match on the search text, not a map radius; a well-known city name works better than a small district. Leave empty to search topics worldwide.["London", "Berlin", "New York"]
searchTopicsNoarray (stringList)One topic or phrase per line, e.g. "comedy", "live music", "yoga". Each topic is combined with each city. Short, common topics return the widest results.["comedy"]
maxCitiesNointegermin 1, max 50Safety cap on the city list. Topics × cities decides how many searches run; cities beyond the cap are simply not searched.5
resolveVenuesNobooleandefault trueAdds the venue name, its own identifier, the venue kind, and a venue page link where the venue is a real Facebook Page. Events with no published venue report an empty venue rather than a made-up one.true
emitVenueRowsNobooleandefault trueAdds one labelled venue row per distinct venue, with event count, cities seen in, and combined interest. Venue rows are also mirrored to their own named dataset for the run.true
requireVenueCityMatchNobooleandefault falseOff: every event is kept and labelled with its city-match confidence. On: an event is kept only if the city name actually appears in its venue text — buys certainty, costs coverage; the coverage rows report exactly how many events were dropped.false
minEventsPerVenueNointegermin 1, max 100Only venues hosting at least this many events in the run get a venue summary row. Never removes event rows, only venue summary rows.1
startUrlsNoarray (stringList)legacy keyThe original actor's search-term list. Used as the topic list when searchTopics is empty. Despite the name, these are search terms, not links — pasting an event link here searches for that link as text and will not return that event.["comedy", "music"]
maxEventsNointegermin 1, max 100000Legacy key. Caps how many events are collected per topic-and-city search before moving to the next one. Higher values load more result pages and take longer. Used as-is; 20 when left empty.20
proxyConfigurationNoobject (proxy editor)prefill: Apify Proxy, RESIDENTIAL groupThe prefilled selection is the one that works most consistently for this source on the Apify platform. Switch it off to run on the direct connection, or pick your own settings — whatever you choose is used exactly as chosen.{ "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }

Input example

{
"cities": ["London", "Berlin", "New York"],
"searchTopics": ["comedy"],
"maxCities": 5,
"resolveVenues": true,
"emitVenueRows": true,
"requireVenueCityMatch": false,
"minEventsPerVenue": 1,
"maxEvents": 20,
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}

Supported input formats

  • Topic-only, no city — leave cities empty and the topic is searched worldwide, with matchedCity reported as null on every event row.
  • Multi-city fan-out — list several cities and several topics; every topic is paired with every city, so 3 topics × 4 cities runs 12 searches.
  • Legacy input file — an input file built for the original actor (startUrls + maxEvents, no cities/searchTopics) is accepted unchanged; startUrls becomes the topic list.

📦 Output Format

Every run writes to a single dataset. Three row kinds share it, told apart by the type field: search_event, cityCoverage, and venue. isChild is false on event rows and true on the two summary row kinds. All three are pushed with charged_event_name: "row_result" — every row in the dataset, of any type, is one billed result; there is no free or uncharged accounting row to filter out.

Output for event rows (type: "search_event")

{
"type": "search_event",
"isChild": false,
"event_id": "2543056406097768",
"title": "Dima Watermelon: Fake European | Stand-Up Comedy in London",
"url": "https://www.facebook.com/events/2543056406097768/",
"query": "comedy in London",
"scrapedAt": "2026-08-10T08:11:58.677130Z",
"searchTopic": "comedy",
"matchedCity": "London",
"matchedCityQuery": "comedy in London",
"resolvedQuery": "comedy in London",
"venueCityMatch": true,
"cityMatchConfidence": "venue_match",
"hasVenue": true,
"venueName": "Big Belly Bar & Comedy Club London",
"venuePlaceId": "779309289128758",
"venuePlaceType": "Page",
"venuePageUrl": "https://www.facebook.com/779309289128758"
}
  • event_id, title, url — the event's own identifier, name, and page link
  • query / matchedCityQuery — the literal search text sent ("<topic> in <city>", or just <topic> with no city)
  • resolvedQuery — the search text Facebook's own response confirms it processed; lets you verify the city and topic actually reached the search
  • searchTopic, matchedCity — which topic and which city search surfaced this row (matchedCity is null when no cities were given)
  • venueCityMatchtrue/false when a city was requested, null when it wasn't
  • cityMatchConfidence"venue_match" or "query_only" when a city was requested, null otherwise
  • hasVenue, venueName, venuePlaceId, venuePlaceType, venuePageUrl — present only when resolveVenues is true; venuePlaceType is "Page" for venues with a real Facebook Page or "FreeformPlace" for address-only venues; venuePageUrl is null for anything that isn't a real Page
  • scrapedAt — UTC ISO-8601 collection timestamp

Output for venue rows (type: "venue")

{
"type": "venue",
"isChild": true,
"venuePlaceId": "779309289128758",
"venueName": "Big Belly Bar & Comedy Club London",
"venuePlaceType": "Page",
"venuePageUrl": "https://www.facebook.com/779309289128758",
"eventCountInRun": 4,
"citiesSeenIn": ["London"],
"totalInterestedAtVenue": 812,
"scrapedAt": "2026-08-10T08:12:41.204558Z"
}
  • venuePlaceId, venueName, venuePlaceType, venuePageUrl — venue identity, same shape as on the event row
  • eventCountInRun — how many distinct events at this venue were collected in this run
  • citiesSeenIn — every city search that surfaced this venue
  • totalInterestedAtVenue — sum of each event's "interested" figure, parsed from Facebook's own attendance text; null when none of the venue's events publish a readable figure — never a fabricated zero
  • Written only when emitVenueRows is true, and only for venues meeting minEventsPerVenue; also mirrored to a <runId>-venues named dataset

Output for city coverage rows (type: "cityCoverage")

{
"type": "cityCoverage",
"isChild": true,
"city": "London",
"searchTopic": "comedy",
"query": "comedy in London",
"resolvedQuery": "comedy in London",
"searchStatus": "ok",
"eventsFound": 20,
"newEventsFound": 18,
"duplicateEventsSkipped": 2,
"duplicateEventIds": ["2543056406097768", "1187456209912340"],
"duplicateWithCities": ["Greater London"],
"droppedByCityFilter": 0,
"venueMatchCount": 17,
"cityHitRatePct": 85.0,
"cityConfirmedInResults": true,
"scrapedAt": "2026-08-10T08:12:41.204558Z"
}
  • city, searchTopic, query, resolvedQuery — what was searched, and what Facebook's own response confirms it processed
  • searchStatus"ok" (results came back and at least one names the city), "no_city_match" (results came back but none name the city), "no_results" (the search ran and genuinely found nothing), "unavailable" (no usable answer came back at all)
  • eventsFound — events this search returned before deduplication
  • newEventsFound — events saved from this search that weren't already saved under an earlier city
  • duplicateEventsSkipped, duplicateEventIds, duplicateWithCities — events this city's search shared with a city already searched earlier in the run, and which cities they were shared with
  • droppedByCityFilter — events removed by requireVenueCityMatch; 0 when that option is off
  • venueMatchCount, cityHitRatePct — how many, and what percentage, of this search's events name the requested city in their venue text
  • cityConfirmedInResultstrue once at least one returned event corroborates the city; null when no city was requested
  • One row per topic-city pair, always — including pairs that returned nothing

Schema stability and export options

Field names stay fixed across runs; a Facebook front-end change that removes a source value produces null on that field rather than a renamed or dropped key. Datasets export from the Apify platform to JSON, CSV, Excel, XML, or RSS, or can be read programmatically through the Dataset API or the apify-client SDK. Venue rows are additionally written to a separate <runId>-venues dataset in the same run for teams that want venues isolated from events without post-filtering.

💡 Facebook Event Scraper Strategy Guide

🎯 Strategy 1: Real-time venue outreach pipeline

Trigger a run on demand with a fresh cities and searchTopics list. Each search_event row that lands carries venueName, venuePlaceId, and venuePageUrl — append these straight into a CRM or spreadsheet as a lead record, keyed on venuePlaceId so the same venue across multiple events collapses to one contact. venueCityMatch and cityMatchConfidence tell you which leads are certain and which are text-relevance matches worth a manual check before outreach.

🎯 Strategy 2: Scheduled scene-monitoring and alerting

Schedule the same cities + searchTopics input on an Apify Schedule and diff each run's cityCoverage rows against the previous run's, keyed on city + searchTopic. A jump in eventsFound or a searchStatus that flips from no_results to ok is the delta worth alerting on — a city that had nothing last week and has events this week.

🎯 Strategy 3: Bulk research dataset build

Run a long cities list paired with a fixed searchTopics list, with maxCities raised to cover the full list. Aggregate the resulting dataset — export it to CSV or pull it via the Dataset API — and group by matchedCity and searchStatus for a city-by-city census of public event activity on a given topic.

Strategy comparison at a glance

StrategyBest forRun patternOutput format
Real-time venue outreachBuilding a warm venue contact list per cityOn-demand, single runDataset rows → CRM/spreadsheet
Scheduled monitoringTracking week-over-week scene activity by cityApify Schedule, recurringDataset rows, diffed run-over-run
Bulk dataset buildResearch or training datasets across many citiesSingle large run, maxCities raisedCSV / JSON export via Dataset API
ScraperWhat it extracts
../../Facebook-Reviews-Scraper/facebook-reviews-scraper-with-date-and-keyword-filtersFacebook Page reviews, filterable by date and keyword
../../Facebook-Video-Transcript-Extractor/facebook-video-transcript-with-caption-extractorFacebook video captions and transcripts

How to integrate Facebook Event Scraper with your stack

Facebook Event Search Scraper By City, Topic & Venue works with any language or tool that can make an HTTP request to the Apify API, or through the official apify-client SDKs.

Python

from apify_client import ApifyClient
import csv
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run_input = {
"cities": ["London", "Berlin", "New York"],
"searchTopics": ["comedy", "live music"],
"maxCities": 5,
"resolveVenues": True,
"emitVenueRows": True,
}
run = client.actor("YOUR_USERNAME/facebook-event-search-scraper-by-city-topic-and-venue").call(
run_input=run_input
)
rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
event_rows = [r for r in rows if r.get("type") == "search_event"]
with open("facebook_events.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=[
"event_id", "title", "url", "matchedCity", "venueName", "venueCityMatch"
])
writer.writeheader()
for row in event_rows:
writer.writerow({k: row.get(k) for k in writer.fieldnames})
print(f"Saved {len(event_rows)} events.")

Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('YOUR_USERNAME/facebook-event-search-scraper-by-city-topic-and-venue').call({
cities: ['London', 'Berlin', 'New York'],
searchTopics: ['comedy'],
maxCities: 5,
resolveVenues: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const events = items.filter((r) => r.type === 'search_event');
console.log(`Collected ${events.length} events.`);

Async and scheduled pipelines

For large city lists, start the run with client.actor(...).start() instead of .call() and poll the run status, or configure an Apify Schedule from the Console to run the same input on a recurring cadence — the Strategy 2 pattern above. Results are always read from the run's dataset after (or during) the run; there is no webhook push built into the Actor itself, but an Apify webhook can be attached to the run to notify an external endpoint on completion.

🎯 Who Needs Facebook Event Scraper? (Use Cases & Industries)

🏢 Local marketing and events agencies

An agency pitching a comedy club or music venue in London pulls every comedy event in that city, reads off venueName and venuePageUrl for every venue already hosting that kind of event, and has a warm-lead list before the first cold call.

📊 AI/RAG and data teams

A local-recommendations assistant indexes title, venueName, and searchTopic from event rows as retrieval documents, so a query about "things to do this weekend" in a given city resolves against real, dated event names rather than generic city guides.

📱 Ticketing and venue-discovery platforms

A venue-discovery app runs the same topic list against a growing city list on a schedule, using eventsFound and cityHitRatePct per city to decide which markets have enough event density to be worth featuring.

🔬 Researchers

Urban studies and cultural-events researchers use the cityCoverage rows as a structured record of what public event activity Facebook's own search surfaces per city and topic — public data only, no private groups or private events.

🎥 Directory and newsletter builders

A "what's on" newsletter or local-events directory schedules a run per city and topic combination it covers, and treats each fresh dataset as its content feed, with scrapedAt giving every entry a freshness stamp.

Scraping publicly accessible data is generally lawful in the United States — hiQ Labs v. LinkedIn Corp., 9th Circuit, 2019, held that scraping data a website makes publicly available does not violate the Computer Fraud and Abuse Act. This Actor returns public event listings and venue records — event titles, venue names, city attribution, and aggregate interest figures — which is business and public-content data, not personal profile data, so GDPR's personal-data framing does not attach to the rows this Actor produces. What can attach is Facebook's own Terms of Service: automated data collection may conflict with them, and a ToS violation is a civil contract matter between the scraper and Facebook, not a criminal one. Facebook Event Search Scraper By City, Topic & Venue returns only publicly accessible data. What you do with that data is your responsibility — consult legal counsel for commercial applications, and if any individual event organizer's personal information appears in your dataset, handle it under the data protection law of your jurisdiction.

❓ Frequently asked questions

Does Facebook Event Scraper work without a Facebook account?

Yes. The Actor reads only Facebook's public, logged-out events search — no login, cookies, or Facebook developer app are required or used anywhere in the code.

How does Facebook Event Scraper handle Facebook's anti-scraping measures?

Requests go through a curl_cffi session impersonating a Chrome browser, with up to 3 attempts per search page (2-second delay between retries) before a search is reported as unavailable. A page is judged by whether it actually carries the results container, never by its HTTP status code, since a non-answer can arrive with the same status as a real one. Network routing goes through whatever proxyConfiguration you select — Apify Proxy on the RESIDENTIAL group by default — or the direct connection if you switch it off.

Can I run Facebook Event Scraper at scale without getting blocked?

Each topic-city search runs its own retry-and-fallback sequence independently, so one failed search never stops the rest of the fan-out. There is no published uptime or success-rate figure for this behaviour — it depends on Facebook's own response to the request pattern at the time of the run.

How fresh is the data Facebook Event Scraper returns?

Every run performs a live fetch against Facebook's current events search; nothing is cached or served from a prior run. scrapedAt on every row is the UTC timestamp of that fetch.

Which fields work best for AI training and RAG indexing?

For RAG retrieval, index title, venueName, and searchTopic — the free-text fields carrying the actual event content. For training data, searchStatus, venueCityMatch, and cityMatchConfidence are the most structurally consistent fields, since each is a fixed enum rather than free text. Every field returns as a typed primitive — string, boolean, number, or null — so none of them need HTML stripping or normalization before use.

Does scraped event data ever include personal information?

Event titles, venue names, and city attribution are business and public-content data, not personal profiles. If a specific event's organizer or venue text happens to include an individual's name, lawful basis for storing and using that fragment of data sits with you as the operator, not with this Actor.

Does Facebook Event Scraper work with Claude, ChatGPT, and other AI agent tools?

It is callable as an HTTP endpoint through the Apify API by any agent framework that can make a request and read JSON — there is no dedicated MCP server for this Actor. Every dataset row returns as typed JSON, ready to drop straight into an LLM context window with no HTML parsing step.

Can I search for events at a specific venue by name?

Not as a direct input. A venue name used as a search term does not reliably return that venue's own events on Facebook's public search, so this Actor treats venue as a resolution and roll-up axis instead: events are collected by topic and city, then grouped by venue afterward in the venue rows.

Why do two cities sometimes report the same event?

Overlapping place names or metro-area terminology can surface the same event under two different city searches. The event is saved once, under whichever city's search found it first; the later city's cityCoverage row records the overlap in duplicateEventsSkipped and names the overlapping cities in duplicateWithCities.

Is my input from the original Facebook Event Search Scraper still valid?

Yes. startUrls, maxEvents, and proxyConfiguration are all still accepted with their original meaning — startUrls is used as the topic list whenever searchTopics is left empty.

ℹ️ Disclaimer

Facebook Event Search Scraper By City, Topic & Venue extracts only publicly available data from Facebook's events search. This tool is intended for lawful use cases only. Users are responsible for complying with Facebook's terms of service and applicable data protection laws in their jurisdiction.

⚠️ Read before relying on scale: each topic-city search is bounded to at most 40 follow-on result pages (roughly 20 events per page), so raising maxEvents toward its schema maximum of 100000 will not return anywhere near that count from a single search — the practical ceiling per topic-city pair is in the hundreds, not tens of thousands. Use a longer cities or searchTopics list, not a larger maxEvents, to grow total dataset size.