# FB Pages Scraper (`devwithbobby/fb-profile-scraper`) Actor

Reliable public Facebook Page scraper with quality-gated results, selective rescue, and controlled diagnostics. Personal profiles are best-effort.

- **URL**: https://apify.com/devwithbobby/fb-profile-scraper.md
- **Developed by:** [Dev with Bobby](https://apify.com/devwithbobby) (community)
- **Categories:** Social media, Lead generation, Integrations
- **Stats:** 1,049 total users, 59 monthly users, 99.9% runs succeeded, 15 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / result

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Scraper

Extract reliable, quality-checked data from **public Facebook Pages**. Personal profiles are accepted as best-effort inputs, but only public Pages are covered by the usable-item reliability target.

The Actor bills a result only when it contains a real Page name, a canonical Facebook URL, and at least one high-value signal: Facebook ID, detected follower/like count (including zero), bio/about text, category, website, email, phone, or address. Image-only identities are rescued when possible and otherwise reported without charge.

### Quick start

Enter Page usernames or URLs, one per line:

```text
nasaearth
Microsoft
https://www.facebook.com/UNICEF
```

Click **Start**, then download usable results as JSON, CSV, or Excel from Storage.

### What you get

- Page name, canonical URL, username, Facebook ID, verification, and category
- Followers and likes, with separate detection flags so zero is not confused with missing data
- About text, website, email, phone, and address when publicly available
- Profile and cover images as supplemental fields
- Quality tier and the exact signals that made the result billable
- Controlled diagnostics for every invalid, blocked, unavailable, identity-only, or timed-out input

Contact fields are best-effort because many Pages do not publish them.

### Input options

| Parameter | Default | Description |
|---|---:|---|
| `profiles` | example Pages | Page usernames or URLs, one per line |
| `mode` | `fast` | Fast, balanced, or deep extraction budget |
| `proxyType` | `BUYPROXIES94952` | Primary datacenter, residential, or static-US proxy |
| `maxConcurrency` | `2` | Concurrent HTTP Page state machines; browser concurrency is always one |
| `maxRequestsPerMinute` | `15` | One global limit shared by HTTP and browser navigation |
| `maxProfiles` | `10` | Maximum unique inputs processed in one run |
| `maxRuntimePerProfileSecs` | `25` | Maximum browser-rescue budget per input |
| `enableResidentialFallback` | `true` | Selective residential rescue for blocks/transient failures |
| `requireAuthenticatedData` | `false` | Use one sticky authenticated browser/proxy identity |
| `cookies` | empty | Optional Facebook cookies as a JSON array |

Blank, malformed, duplicate, and unsupported Facebook URLs are handled inside the Actor. They do not cause a platform-level failed run.

### Output example

The exact fields vary with what a Page publishes. A current result has this shape:

```json
{
  "inputUrl": "https://www.facebook.com/nasaearth",
  "scrapedUrl": "https://www.facebook.com/nasaearth",
  "profileType": "page",
  "supportedScope": "public_page",
  "name": "NASA Earth",
  "username": "nasaearth",
  "followers": 10900000,
  "followersDetected": true,
  "likesDetected": false,
  "about": "Exploring our home planet.",
  "qualitySignals": ["followers", "about"],
  "dataQualityTier": "core",
  "resultStatus": "success",
  "isUsable": true,
  "attemptCount": 1,
  "fallbackStages": ["primary_http"],
  "extractionStage": "primary_http"
}
```

Existing successful-result fields are preserved. The quality fields are additive:

- `dataQualityTier`: `core` or `enriched`
- `qualitySignals`: fields satisfying the high-value contract
- `followersDetected` / `likesDetected`: distinguishes a legitimate zero from missing data
- `supportedScope`: `public_page` for supported Pages or `best_effort_profile` for personal profiles

### Reliability and diagnostics

**Actor run success** means the run finished cleanly and assigned every input a controlled terminal outcome. **Item success** means genuinely usable Page data was produced.

Only `core` and `enriched` results enter the billable default dataset. Everything else is stored in the `FAILURES` key-value record. The output page links to:

- `SUMMARY`: requested/processed counts, public-Page and best-effort-profile counts, Page and overall item success, quality tiers, count-detection rate, stage/rescue counts, reasons, duration, deadline stops, and resource settings
- `FAILURES`: per-input terminal outcomes that were not billed
- `SUPPORT_BUNDLE`: sanitized build/run IDs, aggregate stages, resource settings, and failure codes

`SUPPORT_BUNDLE` never contains Page inputs, cookies, contact data, or proxy credentials.

The Actor has a 540-second soft deadline under the 600-second platform timeout. It stops starting a stage when the measured remaining-time requirement no longer fits, persists a terminal outcome for every input, writes diagnostics, and exits cleanly.

### Extraction pipeline

Each input moves through a bounded state machine:

1. Primary HTTP extraction
2. One residential HTTP rescue for blocks or transient errors, when enabled
3. One single-concurrency browser rescue only while core Page data is missing

Only timeouts, connection failures, and HTTP 5xx responses are retried. Invalid, private, and unavailable inputs terminate immediately. One shared limiter governs every HTTP request and browser navigation.

`enableResidentialFallback=false` keeps browser rescue on the primary proxy. It does not silently switch browser traffic to residential.

### Authentication

Authenticated mode requires valid `c_user` and `xs` cookies. Missing or malformed cookies return `INVALID_OR_EXPIRED_COOKIES` without network work.

```json
[
  {"name": "c_user", "value": "YOUR_USER_ID", "domain": ".facebook.com"},
  {"name": "xs", "value": "YOUR_SESSION", "domain": ".facebook.com"}
]
```

The entire authenticated run uses concurrency one, one crawler session, and one sticky proxy identity. If Facebook sends that session to a checkpoint, the Actor stops using it instead of replaying the cookies through another IP.

Cookies are sensitive and expire. Store them only in the secret input field and export fresh cookies from an account you are authorized to use.

### Scope and limitations

- The supported product is public Facebook Pages.
- Personal profiles are best-effort and excluded from the public-Page SLO. They are billed only when they satisfy the same high-value contract.
- Private data is not accessed.
- Facebook can change markup, present login walls, or temporarily block traffic.
- Page contact fields are not guaranteed.

### Pricing

Pricing remains **$0.01 per usable result**. Failed and identity-only outcomes stay out of the default dataset and are not billed as results.

### Support

When reporting a problem, share the sanitized `SUPPORT_BUNDLE` record and the run link. Do not send Facebook cookies or proxy credentials.

# Actor input Schema

## `profiles` (type: `string`):

Enter public Facebook Page usernames or URLs, one per line. Personal profiles are accepted on a best-effort basis. Blank and malformed inputs are reported as controlled failures instead of failing the Actor run.

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

Controls cost versus completeness. Every mode starts with lightweight extraction and uses browser rescue only when core Page data is still missing.

## `proxyType` (type: `string`):

Select the primary proxy type. The Actor falls back to automatic Apify Proxy if the selected group is unavailable, and uses residential rescue only for blocked profiles when enabled.

## `maxConcurrency` (type: `integer`):

Maximum concurrent HTTP Page state machines. Browser rescue always remains at concurrency one.

## `maxRequestsPerMinute` (type: `integer`):

One global rate limit shared by every HTTP request and browser navigation.

## `cookies` (type: `string`):

Optional: Paste your Facebook cookies as JSON array for authenticated scraping. This allows access to more profile data.

Format: \[{"name": "c\_user", "value": "...", "domain": ".facebook.com"}, ...]

You can export cookies using browser extensions like 'Cookie-Editor' or 'EditThisCookie'.

## `maxProfiles` (type: `integer`):

Maximum inputs to process in one run. Additional inputs are not started, keeping runtime and cost bounded.

## `maxRuntimePerProfileSecs` (type: `integer`):

Maximum browser fallback budget per profile. The Actor may reduce this dynamically so it can finish and write diagnostics before the 10-minute run deadline.

## `requireAuthenticatedData` (type: `boolean`):

Use one sticky browser/proxy identity for the whole run. Valid c\_user and xs cookies are required; invalid cookies are rejected without network work.

## `enableResidentialFallback` (type: `boolean`):

Use residential HTTP and browser rescue only for blocked or transient Page attempts. When disabled, browser rescue remains on the configured primary proxy.

## Actor input object example

```json
{
  "profiles": "nasaearth\nMicrosoft\nhttps://www.facebook.com/UNICEF",
  "mode": "fast",
  "proxyType": "BUYPROXIES94952",
  "maxConcurrency": 2,
  "maxRequestsPerMinute": 15,
  "maxProfiles": 10,
  "maxRuntimePerProfileSecs": 25,
  "requireAuthenticatedData": false,
  "enableResidentialFallback": true
}
```

# Actor output Schema

## `overview` (type: `string`):

Quick overview of scraped profiles with key metrics

## `contact` (type: `string`):

Email, phone, website and address for each profile

## `detailed` (type: `string`):

Full data for all scraped profiles

## `allData` (type: `string`):

Complete raw JSON data

## `summary` (type: `string`):

Statistics about the scraping run

## `failures` (type: `string`):

Invalid, blocked, unavailable, timed-out, and internal-error outcomes that were not added to the billable dataset

## `supportBundle` (type: `string`):

Build, resource, stage, and failure-code diagnostics without inputs, cookies, contact data, or proxy credentials

# 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 = {
    "profiles": `nasaearth
Microsoft
https://www.facebook.com/UNICEF`
};

// Run the Actor and wait for it to finish
const run = await client.actor("devwithbobby/fb-profile-scraper").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 = { "profiles": """nasaearth
Microsoft
https://www.facebook.com/UNICEF""" }

# Run the Actor and wait for it to finish
run = client.actor("devwithbobby/fb-profile-scraper").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 '{
  "profiles": "nasaearth\\nMicrosoft\\nhttps://www.facebook.com/UNICEF"
}' |
apify call devwithbobby/fb-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,devwithbobby/fb-profile-scraper"
        }
    }
}

```

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/zQt0UcNu0fsd98YAw/builds/sP819S1QabYdsLvrW/openapi.json
