# Facebook Pages Search Scraper (contacts, followers, no login) (`datahamster/facebook-pages-search`) Actor

Facebook page search by keyword or city: get every public Page as one row with likes, followers, category, website, phone, email, address, rating and description. No login, no cookies. Monitor mode alerts on follower and category changes; you pay only for the Page rows you get.

- **URL**: https://apify.com/datahamster/facebook-pages-search.md
- **Developed by:** [Viktor Dubnytskiy](https://apify.com/datahamster) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 result items

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Facebook Pages Search Scraper (contacts, followers, no login)

Search Facebook Pages by keyword, business type or city and get one flat row per Page: likes, followers, category, website, phone, email, street address, rating and description. No Facebook account, no cookies, no session — the actor reads only what Facebook serves to logged-out visitors.

### What you get

One row per Page: `id`/`slug`, `url`, `pageId`, `profileId`, `name`, `city`, `category`, `likes`, `followers`, `followersText`, `talkingAbout`, `wereHere`, `verified`, `description`, `website`, `websiteText`, `phone`, `email`, `address`, `responsibleEntity`, `rating`, `priceRange`, `hours`, `profilePictureUrl`, `available`, `detailsFetched`, `query`, `rank`, `source`, `scrapedAt`.

Contacts are the business details the Page publishes in its own Intro card. No admins, no members, no personal profiles.

### Example output

Real rows from the example dataset (query `yoga kyiv`):

| Field | Example value |
|---|---|
| `url` | `https://www.facebook.com/kievyogastudio/` |
| `name` / `category` | `Kiev Yoga Studio` / `Yoga Studio` |
| `likes` / `followers` | `1385` / `1300` ("1.3K followers") |
| `website` | `http://www.kievyogastudio.com/` |
| `phone` / `email` | `+380 68 308 3798` / `kys.sattva@gmail.com` |
| `address` / `city` | `Руденко, 6А, Kyiv, Ukraine` / `Kyiv` |
| `rating` / `priceRange` | `92% recommend (8 reviews)` / `$$` |
| `pageId` | `576068382819638` |

### Use cases

- Build a local B2B list for one city and one business type, with the website, phone and email the business itself published.
- Map competitors in a niche and compare their follower counts, categories and ratings side by side.
- Watch a set of Pages and get an alert when followers, name or category change.

### How it works

1. **Discovery** — each keyword is searched in a public search-engine index restricted to `facebook.com`, so you get Pages Facebook itself has published to the open web. Post and photo links collapse into their Page; groups, events and people profiles are skipped.
2. **Enrichment** (`fetchDetails`) — each Page is opened as a logged-out visitor to read the counters and the Intro card (category, website, phone, email, address, hours, price range, rating). Pages Facebook does not serve logged-out come back with `available: false`.
3. Empty search answers are retried once and reported as a block, so an empty dataset never hides a wall.

### Input

| Field | Meaning | Default |
|---|---|---|
| `queries` | Keywords to search Pages for, e.g. `yoga kyiv`, `dentist berlin` | `["yoga kyiv"]` |
| `pageUrls` | Known Page URLs to enrich directly | empty |
| `resultsPerQuery` | Search hits scanned per keyword (1-200) | `10` |
| `fetchDetails` | Open each Page for counters and contacts | `true` |
| `maxItems` | Stop after this many Page rows | `20` |
| `mode` | `scrape` or `monitor` (only new/changed since last run) | `scrape` |
| `monitorKey`, `webhookUrl`, `telegramBotToken`, `telegramChatId` | Monitor-mode state key and alert targets | empty |

### Pricing

| Event | Price |
|---|---|
| result | $0.003 per page ($3 per 1,000) |
| monitor-check | $0.006 per monitor run |
| change | $0.003 per new/changed page |

Charged only for pages actually pushed. Residential proxy traffic is billed by Apify on top (pages hit a login wall from datacenter IPs).

### Why this actor

- No login and no cookies to supply — nothing to keep alive, nothing to get banned.
- Business contacts (website, phone, email, address) come out of the same run, so there is no second enrichment step.
- Monitor mode with webhook and Telegram alerts on follower, name and category changes.
- A run that finds nothing pushes nothing and charges no result events; the run summary explains why instead of leaving you guessing.

### Limits

- Facebook's own page search needs a login and is not used; discovery depends on the search-engine index, which favours pages with public activity. Very small or freshly created pages may be missing.
- Counters are what Facebook shows logged-out visitors (`followers` is rounded, e.g. "1.9K"; `likes` is exact).
- No posts, reviews text, admins or followers lists — only page-level facts.

### FAQ

**Does it need a Facebook login or cookies?** No. There is no account or cookie field at all; every request is made as a logged-out visitor.

**What happens when there are no results?** No rows are pushed and no result events are charged. The `RUN_SUMMARY` record in the run's key-value store carries `emptyReason`, which separates "the keyword has no public Pages" from "the search index answered with a challenge".

**Is the email a personal contact?** No. `email`, `phone` and `website` are the business details the Page publishes in its public Intro card. The actor returns no admins, no followers and no personal profiles.

### Changelog

- 0.1: initial release — keyword discovery, page enrichment with contacts, monitor mode; empty search results are retried and reported as a block instead of an empty dataset.

***

If this actor saved you time, a short review on its Store page genuinely helps other people find it. Found a bug or need a field that is missing? Open a ticket on the **Issues** tab.

# Actor input Schema

## `queries` (type: `array`):

Keywords to search public Facebook Pages for, one per line, e.g. "yoga kyiv", "dentist berlin", "coworking lisbon", "vegan bakery". Combine a business type with a city for local lists.

## `pageUrls` (type: `array`):

Known Facebook Page URLs to enrich directly, e.g. "https://www.facebook.com/kievyogastudio/" or "https://www.facebook.com/profile.php?id=576068382819638". Can be combined with Search queries or used alone.

## `resultsPerQuery` (type: `integer`):

How many search hits to scan per keyword, e.g. 10. More hits mean more Pages but a longer run; after de-duplication the number of Pages is usually lower. Range 1-200.

## `fetchDetails` (type: `boolean`):

true = open each Page as a logged-out visitor to read likes, followers, category, website, phone, email, address, hours and rating (one extra request per Page). false = return only the URL, slug and name found by search. Example: true.

## `maxItems` (type: `integer`):

Stop after this many Page rows, e.g. 20. You are charged only for rows actually pushed to the dataset.

## `mode` (type: `string`):

"scrape" returns every matching row. "monitor" returns only rows that are new or whose likes, followers, name or category changed since the previous run of the same saved task. Example: "scrape".

## `monitorKey` (type: `string`):

Optional state key for monitor mode when the actor is not run as a saved task, e.g. "dentists-berlin-weekly". Runs sharing a key share the comparison state.

## `webhookUrl` (type: `string`):

Optional HTTPS URL that receives a POST with a JSON summary of the changes found in monitor mode, e.g. "https://hooks.zapier.com/hooks/catch/123/abc".

## `telegramBotToken` (type: `string`):

Optional Telegram bot token used to send monitor-mode change summaries, e.g. "123456789:AAE...". Leave empty to skip Telegram alerts.

## `telegramChatId` (type: `string`):

Optional Telegram chat id that receives the monitor-mode summaries, e.g. "-1001234567890" for a channel or "123456789" for a direct chat.

## Actor input object example

```json
{
  "queries": [
    "yoga kyiv"
  ],
  "resultsPerQuery": 10,
  "fetchDetails": true,
  "maxItems": 20,
  "mode": "scrape"
}
```

# Actor output Schema

## `results` (type: `string`):

All pushed rows (dataset, JSON)

## `resultsTable` (type: `string`):

Dataset in the Console viewer

## `runSummary` (type: `string`):

RUN\_SUMMARY record

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "yoga kyiv"
    ],
    "resultsPerQuery": 10,
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("datahamster/facebook-pages-search").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": ["yoga kyiv"],
    "resultsPerQuery": 10,
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("datahamster/facebook-pages-search").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "yoga kyiv"
  ],
  "resultsPerQuery": 10,
  "maxItems": 20
}' |
apify call datahamster/facebook-pages-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datahamster/facebook-pages-search"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/1U3yS7uMQlmota7rY/builds/Z9dvtOjiROzXfmPWh/openapi.json
