# Facebook Reels Play Count Scraper (`social_developer/facebook-playcount-scraper`) Actor

Scrapes exact play counts for Facebook video / reel / watch URLs. Uses Apify datacenter proxies for IP rotation.

- **URL**: https://apify.com/social\_developer/facebook-playcount-scraper.md
- **Developed by:** [Rishab](https://apify.com/social_developer) (community)
- **Categories:** Social media
- **Stats:** 17 total users, 11 monthly users, 94.7% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.00005 / actor start

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Video Play Count Scraper — Apify Actor

An [Apify Actor](https://docs.apify.com/platform/actors) that extracts the exact `play_count`
for Facebook video / reel / watch URLs, using **Apify datacenter proxies** for IP rotation.

It is a port of the original local CLI scraper (`facebook_playcount_scraper.py`) to the
Apify platform, so the detection logic (video-id extraction + HTML parsing) is unchanged.

### What it does

1. Takes a list of Facebook URLs (via `startUrls` or a pasted `urlsText` block).
2. Extracts the numeric video id from each URL (`?v=`, `/videos/…`, `/reel/…`, `/watch/…`).
3. **Reel URLs are auto-converted** before scraping: `/reel/{id}` → `https://www.facebook.com/watch/?v={id}`. Watch URLs are used as-is.
4. Fetches the page HTML (optionally through Apify proxy), rotating the IP on every retry.
5. Parses the exact `play_count` for the target video id from the embedded JSON payloads.
6. Pushes one record per URL to the actor's default dataset.

#### Output record shape

```json
{
    "url": "https://www.facebook.com/watch/?v=1234567890",
    "video_id": "1234567890",
    "play_count": 482311,
    "status": "ok"
}
````

`status` is one of:

- `ok` — play count found.
- `invalid_video_id` — URL did not contain a recognisable video id.
- `play_count_not_found` — page fetched, but no matching play count in HTML.
- `request_failed: …` — all retries failed. The suffix indicates the last error
  (e.g. `http_429`, `timeout`, `request_failed: ConnectError`).

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array of `{url}` | — | Facebook URLs to scrape. |
| `urlsText` | string | — | Alternative to `startUrls`, one URL per line. |
| `maxConcurrency` | int | `12` | Parallel fetches. |
| `requestTimeoutSecs` | int | `20` | Per-request HTTP timeout. |
| `maxRetriesPerUrl` | int | `3` | Retries per URL, each with a fresh proxy IP. |
| `useProxy` | bool | `true` | Toggle proxy usage. Set `false` to run with no proxy (direct actor IP). |
| `proxyConfiguration` | object | `{ useApifyProxy: true, apifyProxyGroups: [] }` | Apify proxy config (ignored when `useProxy` is `false`). |

Example input lives at [`.actor/input.example.json`](./.actor/input.example.json).

### IP rotation

The actor calls `Actor.create_proxy_configuration(actor_proxy_input=…)` and then
requests a **new proxy URL per attempt** with a unique `session_id`, so every retry
is guaranteed to go through a different upstream Apify datacenter IP:

```python
proxy_url = await proxy_configuration.new_url(
    session_id=f"fb_{abs(hash(url))}_{attempt}"
)
```

That session id is also what Apify uses to pin a given IP — by bumping the attempt
counter, we explicitly break stickiness after a failure, which is the usual pattern
for recovering from rate-limits/soft-blocks on datacenter proxies.

If you want residential proxies instead, edit the input and pass:

```json
"proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
}
```

### Local development

Requires Python 3.11 and the Apify CLI.

```bash
## from the project root
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

## install Apify CLI (one-time, via npm)
npm install -g apify-cli

## run the actor locally using the example input
apify run --purge --input-file=.actor/input.example.json
```

Results land in `storage/datasets/default/`.

### Deploy to the Apify platform

```bash
apify login        ## paste your Apify API token
apify push         ## builds the Docker image and pushes the actor
```

`apify push` uses `.actor/actor.json` + `.actor/Dockerfile` to build the actor on
Apify, and `.actor/input_schema.json` to render the input form in the Apify Console.

After the push you can either:

- Run it from the Apify Console UI.
- Trigger it from the API:

  ```bash
  curl -X POST "https://api.apify.com/v2/acts/<USERNAME>~facebook-playcount-scraper/runs?token=$APIFY_TOKEN" \
       -H "Content-Type: application/json" \
       -d @.actor/input.example.json
  ```

### Project layout

```
.
├── .actor/
│   ├── actor.json            ## actor metadata + dataset view
│   ├── Dockerfile            ## build config (apify/actor-python:3.11)
│   ├── input_schema.json     ## UI / API input schema
│   └── input.example.json    ## sample input for `apify run`
├── src/
│   ├── __main__.py           ## `python -m src` entrypoint
│   ├── main.py               ## Apify actor logic + proxy rotation
│   └── parser.py             ## video-id + play_count extraction
├── facebook_playcount_scraper.py  ## original standalone CLI (kept for reference)
├── requirements.txt
├── .dockerignore
├── .gitignore
└── README.md
```

### Push to GitHub

```bash
git init
git add .
git commit -m "Apify actor: facebook play count scraper with DATACENTER proxy rotation"
git branch -M main
git remote add origin https://github.com/shanskarBansal/facebook-playcount-scraper.git
git push -u origin main
```

# Actor input Schema

## `startUrls` (type: `array`):

List of Facebook video / reel / watch URLs to scrape play counts for. Reel links like https://www.facebook.com/reel/123456789 are automatically converted to https://www.facebook.com/watch/?v=123456789 before scraping.

## `urlsText` (type: `string`):

Alternative to startUrls. Plain-text list of URLs, one per line. Useful for pasting large batches.

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

Number of URLs to fetch in parallel.

## `requestTimeoutSecs` (type: `integer`):

HTTP request timeout per URL.

## `maxRetriesPerUrl` (type: `integer`):

How many times to retry a URL with a fresh proxy IP before giving up.

## `useProxy` (type: `boolean`):

Enable Apify proxy routing. Turn this OFF to run directly from the actor IP (no proxy).

## `proxyConfiguration` (type: `object`):

Apify proxy settings. Defaults to Apify datacenter proxies (auto-selected per plan) for IP rotation. On paid plans you can explicitly set `apifyProxyGroups: ["DATACENTER"]`, and `["RESIDENTIAL"]` is also supported.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.facebook.com/watch/?v=1234567890"
    }
  ],
  "maxConcurrency": 12,
  "requestTimeoutSecs": 20,
  "maxRetriesPerUrl": 3,
  "useProxy": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": []
  }
}
```

# 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 = {
    "startUrls": [
        {
            "url": "https://www.facebook.com/watch/?v=1234567890"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": []
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("social_developer/facebook-playcount-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 = {
    "startUrls": [{ "url": "https://www.facebook.com/watch/?v=1234567890" }],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": [],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("social_developer/facebook-playcount-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.facebook.com/watch/?v=1234567890"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": []
  }
}' |
apify call social_developer/facebook-playcount-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=social_developer/facebook-playcount-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Facebook Reels Play Count Scraper",
        "description": "Scrapes exact play counts for Facebook video / reel / watch URLs. Uses Apify datacenter proxies for IP rotation.",
        "version": "0.1",
        "x-build-id": "1dtXOjG7DybPzVZky"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/social_developer~facebook-playcount-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-social_developer-facebook-playcount-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/social_developer~facebook-playcount-scraper/runs": {
            "post": {
                "operationId": "runs-sync-social_developer-facebook-playcount-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/social_developer~facebook-playcount-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-social_developer-facebook-playcount-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "startUrls": {
                        "title": "Facebook video URLs",
                        "type": "array",
                        "description": "List of Facebook video / reel / watch URLs to scrape play counts for. Reel links like https://www.facebook.com/reel/123456789 are automatically converted to https://www.facebook.com/watch/?v=123456789 before scraping.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "urlsText": {
                        "title": "Or paste URLs (one per line)",
                        "type": "string",
                        "description": "Alternative to startUrls. Plain-text list of URLs, one per line. Useful for pasting large batches."
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Number of URLs to fetch in parallel.",
                        "default": 12
                    },
                    "requestTimeoutSecs": {
                        "title": "Request timeout (seconds)",
                        "minimum": 5,
                        "maximum": 120,
                        "type": "integer",
                        "description": "HTTP request timeout per URL.",
                        "default": 20
                    },
                    "maxRetriesPerUrl": {
                        "title": "Max retries per URL",
                        "minimum": 0,
                        "maximum": 10,
                        "type": "integer",
                        "description": "How many times to retry a URL with a fresh proxy IP before giving up.",
                        "default": 3
                    },
                    "useProxy": {
                        "title": "Use proxy",
                        "type": "boolean",
                        "description": "Enable Apify proxy routing. Turn this OFF to run directly from the actor IP (no proxy).",
                        "default": true
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify proxy settings. Defaults to Apify datacenter proxies (auto-selected per plan) for IP rotation. On paid plans you can explicitly set `apifyProxyGroups: [\"DATACENTER\"]`, and `[\"RESIDENTIAL\"]` is also supported.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": []
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
