# Facebook Ads Scraper

Facebook Ads Library Scraper - Lightning Fast Edition | Extract Active Facebook Ads Data Instantly. Scrape ads by country & keyword with ultra-fast HTML parsing. Perfect for marketing research, competitor analysis & lead generation. Headless browser automation with Playwright & Apify.

## Actor Statistics

- Total users: 28
- Monthly users: 18
- Runs succeeded: 100.00%
- Categories: Automation, Lead generation, Real estate

## Pricing

$0.70 / 1,000 results

## Input Schema

- **targets** (type: array): Array of country-keyword pairs to scrape ads for
- **adsLimit** (type: integer): Maximum number of ads to scrape per country-keyword pair
- **scrollCount** (type: integer): Number of times to scroll down to load more ads
- **headless** (type: boolean): Run browser in headless mode for better performance
- **maxConcurrency** (type: integer): Maximum number of concurrent browser instances (optimize for memory)
- **delay** (type: integer): Delay in milliseconds between actions to avoid rate limiting

## API example

## Facebook Ads Scraper

- **OpenAPI Version:** `3.1.1`
- **API Version:** `0.0`

Facebook Ads Library Scraper - Lightning Fast Edition | Extract Active Facebook Ads Data Instantly. Scrape ads by country & keyword with ultra-fast HTML parsing. Perfect for marketing research, competitor analysis & lead generation. Headless browser automation with Playwright & Apify.

### Servers

- **URL:** `https://api.apify.com/v2`

### Operations

#### Executes an Actor, waits for its completion, and returns Actor's dataset items in response.

- **Method:** `POST`
- **Path:** `/acts/shahzeb-king~facebook-ads-scraper/run-sync-get-dataset-items`
- **Tags:** Run Actor

##### Request Body

###### Content-Type: application/json

- **`targets` (required)**

  `array` — Array of country-keyword pairs to scrape ads for

- **`adsLimit`**

  `integer`, default: `100` — Maximum number of ads to scrape per country-keyword pair

- **`delay`**

  `integer`, default: `2000` — Delay in milliseconds between actions to avoid rate limiting

- **`headless`**

  `boolean`, default: `true` — Run browser in headless mode for better performance

- **`maxConcurrency`**

  `integer`, default: `1` — Maximum number of concurrent browser instances (optimize for memory)

- **`scrollCount`**

  `integer`, default: `1` — Number of times to scroll down to load more ads

**Example:**

```
{
  "targets": [],
  "adsLimit": 100,
  "scrollCount": 1,
  "headless": true,
  "maxConcurrency": 1,
  "delay": 2000
}
```

##### Responses

###### Status: 200 OK

#### Executes an Actor and returns information about the initiated run in response.

- **Method:** `POST`
- **Path:** `/acts/shahzeb-king~facebook-ads-scraper/runs`
- **Tags:** Run Actor

##### Request Body

###### Content-Type: application/json

- **`targets` (required)**

  `array` — Array of country-keyword pairs to scrape ads for

- **`adsLimit`**

  `integer`, default: `100` — Maximum number of ads to scrape per country-keyword pair

- **`delay`**

  `integer`, default: `2000` — Delay in milliseconds between actions to avoid rate limiting

- **`headless`**

  `boolean`, default: `true` — Run browser in headless mode for better performance

- **`maxConcurrency`**

  `integer`, default: `1` — Maximum number of concurrent browser instances (optimize for memory)

- **`scrollCount`**

  `integer`, default: `1` — Number of times to scroll down to load more ads

**Example:**

```
{
  "targets": [],
  "adsLimit": 100,
  "scrollCount": 1,
  "headless": true,
  "maxConcurrency": 1,
  "delay": 2000
}
```

##### Responses

###### Status: 200 OK

\####### Content-Type: application/json

- **`data`**

  `object`

  - **`actId`**

    `string`

  - **`buildId`**

    `string`

  - **`buildNumber`**

    `string`

  - **`containerUrl`**

    `string`

  - **`defaultDatasetId`**

    `string`

  - **`defaultKeyValueStoreId`**

    `string`

  - **`defaultRequestQueueId`**

    `string`

  - **`finishedAt`**

    `string`, format: `date-time`

  - **`id`**

    `string`

  - **`meta`**

    `object`

    - **`origin`**

      `string`

    - **`userAgent`**

      `string`

  - **`options`**

    `object`

    - **`build`**

      `string`

    - **`diskMbytes`**

      `integer`

    - **`memoryMbytes`**

      `integer`

    - **`timeoutSecs`**

      `integer`

  - **`startedAt`**

    `string`, format: `date-time`

  - **`stats`**

    `object`

    - **`computeUnits`**

      `integer`

    - **`inputBodyLen`**

      `integer`

    - **`rebootCount`**

      `integer`

    - **`restartCount`**

      `integer`

    - **`resurrectCount`**

      `integer`

  - **`status`**

    `string`

  - **`usage`**

    `object`

    - **`ACTOR_COMPUTE_UNITS`**

      `integer`

    - **`DATA_TRANSFER_EXTERNAL_GBYTES`**

      `integer`

    - **`DATA_TRANSFER_INTERNAL_GBYTES`**

      `integer`

    - **`DATASET_READS`**

      `integer`

    - **`DATASET_WRITES`**

      `integer`

    - **`KEY_VALUE_STORE_LISTS`**

      `integer`

    - **`KEY_VALUE_STORE_READS`**

      `integer`

    - **`KEY_VALUE_STORE_WRITES`**

      `integer`

    - **`PROXY_RESIDENTIAL_TRANSFER_GBYTES`**

      `integer`

    - **`PROXY_SERPS`**

      `integer`

    - **`REQUEST_QUEUE_READS`**

      `integer`

    - **`REQUEST_QUEUE_WRITES`**

      `integer`

  - **`usageTotalUsd`**

    `number`

  - **`usageUsd`**

    `object`

    - **`ACTOR_COMPUTE_UNITS`**

      `integer`

    - **`DATA_TRANSFER_EXTERNAL_GBYTES`**

      `integer`

    - **`DATA_TRANSFER_INTERNAL_GBYTES`**

      `integer`

    - **`DATASET_READS`**

      `integer`

    - **`DATASET_WRITES`**

      `integer`

    - **`KEY_VALUE_STORE_LISTS`**

      `integer`

    - **`KEY_VALUE_STORE_READS`**

      `integer`

    - **`KEY_VALUE_STORE_WRITES`**

      `number`

    - **`PROXY_RESIDENTIAL_TRANSFER_GBYTES`**

      `integer`

    - **`PROXY_SERPS`**

      `integer`

    - **`REQUEST_QUEUE_READS`**

      `integer`

    - **`REQUEST_QUEUE_WRITES`**

      `integer`

  - **`userId`**

    `string`

**Example:**

```
{
  "data": {
    "id": "",
    "actId": "",
    "userId": "",
    "startedAt": "2025-01-08T00:00:00.000Z",
    "finishedAt": "2025-01-08T00:00:00.000Z",
    "status": "READY",
    "meta": {
      "origin": "API",
      "userAgent": ""
    },
    "stats": {
      "inputBodyLen": 2000,
      "rebootCount": 0,
      "restartCount": 0,
      "resurrectCount": 0,
      "computeUnits": 0
    },
    "options": {
      "build": "latest",
      "timeoutSecs": 300,
      "memoryMbytes": 1024,
      "diskMbytes": 2048
    },
    "buildId": "",
    "defaultKeyValueStoreId": "",
    "defaultDatasetId": "",
    "defaultRequestQueueId": "",
    "buildNumber": "1.0.0",
    "containerUrl": "",
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0,
      "DATASET_READS": 0,
      "DATASET_WRITES": 0,
      "KEY_VALUE_STORE_READS": 0,
      "KEY_VALUE_STORE_WRITES": 1,
      "KEY_VALUE_STORE_LISTS": 0,
      "REQUEST_QUEUE_READS": 0,
      "REQUEST_QUEUE_WRITES": 0,
      "DATA_TRANSFER_INTERNAL_GBYTES": 0,
      "DATA_TRANSFER_EXTERNAL_GBYTES": 0,
      "PROXY_RESIDENTIAL_TRANSFER_GBYTES": 0,
      "PROXY_SERPS": 0
    },
    "usageTotalUsd": 0.00005,
    "usageUsd": {
      "ACTOR_COMPUTE_UNITS": 0,
      "DATASET_READS": 0,
      "DATASET_WRITES": 0,
      "KEY_VALUE_STORE_READS": 0,
      "KEY_VALUE_STORE_WRITES": 0.00005,
      "KEY_VALUE_STORE_LISTS": 0,
      "REQUEST_QUEUE_READS": 0,
      "REQUEST_QUEUE_WRITES": 0,
      "DATA_TRANSFER_INTERNAL_GBYTES": 0,
      "DATA_TRANSFER_EXTERNAL_GBYTES": 0,
      "PROXY_RESIDENTIAL_TRANSFER_GBYTES": 0,
      "PROXY_SERPS": 0
    }
  }
}
```

#### Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.

- **Method:** `POST`
- **Path:** `/acts/shahzeb-king~facebook-ads-scraper/run-sync`
- **Tags:** Run Actor

##### Request Body

###### Content-Type: application/json

- **`targets` (required)**

  `array` — Array of country-keyword pairs to scrape ads for

- **`adsLimit`**

  `integer`, default: `100` — Maximum number of ads to scrape per country-keyword pair

- **`delay`**

  `integer`, default: `2000` — Delay in milliseconds between actions to avoid rate limiting

- **`headless`**

  `boolean`, default: `true` — Run browser in headless mode for better performance

- **`maxConcurrency`**

  `integer`, default: `1` — Maximum number of concurrent browser instances (optimize for memory)

- **`scrollCount`**

  `integer`, default: `1` — Number of times to scroll down to load more ads

**Example:**

```
{
  "targets": [],
  "adsLimit": 100,
  "scrollCount": 1,
  "headless": true,
  "maxConcurrency": 1,
  "delay": 2000
}
```

##### Responses

###### Status: 200 OK

### Schemas

#### inputSchema

- **Type:**`object`

* **`targets` (required)**

  `array` — Array of country-keyword pairs to scrape ads for

* **`adsLimit`**

  `integer`, default: `100` — Maximum number of ads to scrape per country-keyword pair

* **`delay`**

  `integer`, default: `2000` — Delay in milliseconds between actions to avoid rate limiting

* **`headless`**

  `boolean`, default: `true` — Run browser in headless mode for better performance

* **`maxConcurrency`**

  `integer`, default: `1` — Maximum number of concurrent browser instances (optimize for memory)

* **`scrollCount`**

  `integer`, default: `1` — Number of times to scroll down to load more ads

**Example:**

```
{
  "targets": [],
  "adsLimit": 100,
  "scrollCount": 1,
  "headless": true,
  "maxConcurrency": 1,
  "delay": 2000
}
```

#### runsResponseSchema

- **Type:**`object`

* **`data`**

  `object`

  - **`actId`**

    `string`

  - **`buildId`**

    `string`

  - **`buildNumber`**

    `string`

  - **`containerUrl`**

    `string`

  - **`defaultDatasetId`**

    `string`

  - **`defaultKeyValueStoreId`**

    `string`

  - **`defaultRequestQueueId`**

    `string`

  - **`finishedAt`**

    `string`, format: `date-time`

  - **`id`**

    `string`

  - **`meta`**

    `object`

    - **`origin`**

      `string`

    - **`userAgent`**

      `string`

  - **`options`**

    `object`

    - **`build`**

      `string`

    - **`diskMbytes`**

      `integer`

    - **`memoryMbytes`**

      `integer`

    - **`timeoutSecs`**

      `integer`

  - **`startedAt`**

    `string`, format: `date-time`

  - **`stats`**

    `object`

    - **`computeUnits`**

      `integer`

    - **`inputBodyLen`**

      `integer`

    - **`rebootCount`**

      `integer`

    - **`restartCount`**

      `integer`

    - **`resurrectCount`**

      `integer`

  - **`status`**

    `string`

  - **`usage`**

    `object`

    - **`ACTOR_COMPUTE_UNITS`**

      `integer`

    - **`DATA_TRANSFER_EXTERNAL_GBYTES`**

      `integer`

    - **`DATA_TRANSFER_INTERNAL_GBYTES`**

      `integer`

    - **`DATASET_READS`**

      `integer`

    - **`DATASET_WRITES`**

      `integer`

    - **`KEY_VALUE_STORE_LISTS`**

      `integer`

    - **`KEY_VALUE_STORE_READS`**

      `integer`

    - **`KEY_VALUE_STORE_WRITES`**

      `integer`

    - **`PROXY_RESIDENTIAL_TRANSFER_GBYTES`**

      `integer`

    - **`PROXY_SERPS`**

      `integer`

    - **`REQUEST_QUEUE_READS`**

      `integer`

    - **`REQUEST_QUEUE_WRITES`**

      `integer`

  - **`usageTotalUsd`**

    `number`

  - **`usageUsd`**

    `object`

    - **`ACTOR_COMPUTE_UNITS`**

      `integer`

    - **`DATA_TRANSFER_EXTERNAL_GBYTES`**

      `integer`

    - **`DATA_TRANSFER_INTERNAL_GBYTES`**

      `integer`

    - **`DATASET_READS`**

      `integer`

    - **`DATASET_WRITES`**

      `integer`

    - **`KEY_VALUE_STORE_LISTS`**

      `integer`

    - **`KEY_VALUE_STORE_READS`**

      `integer`

    - **`KEY_VALUE_STORE_WRITES`**

      `number`

    - **`PROXY_RESIDENTIAL_TRANSFER_GBYTES`**

      `integer`

    - **`PROXY_SERPS`**

      `integer`

    - **`REQUEST_QUEUE_READS`**

      `integer`

    - **`REQUEST_QUEUE_WRITES`**

      `integer`

  - **`userId`**

    `string`

**Example:**

```
{
  "data": {
    "id": "",
    "actId": "",
    "userId": "",
    "startedAt": "2025-01-08T00:00:00.000Z",
    "finishedAt": "2025-01-08T00:00:00.000Z",
    "status": "READY",
    "meta": {
      "origin": "API",
      "userAgent": ""
    },
    "stats": {
      "inputBodyLen": 2000,
      "rebootCount": 0,
      "restartCount": 0,
      "resurrectCount": 0,
      "computeUnits": 0
    },
    "options": {
      "build": "latest",
      "timeoutSecs": 300,
      "memoryMbytes": 1024,
      "diskMbytes": 2048
    },
    "buildId": "",
    "defaultKeyValueStoreId": "",
    "defaultDatasetId": "",
    "defaultRequestQueueId": "",
    "buildNumber": "1.0.0",
    "containerUrl": "",
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0,
      "DATASET_READS": 0,
      "DATASET_WRITES": 0,
      "KEY_VALUE_STORE_READS": 0,
      "KEY_VALUE_STORE_WRITES": 1,
      "KEY_VALUE_STORE_LISTS": 0,
      "REQUEST_QUEUE_READS": 0,
      "REQUEST_QUEUE_WRITES": 0,
      "DATA_TRANSFER_INTERNAL_GBYTES": 0,
      "DATA_TRANSFER_EXTERNAL_GBYTES": 0,
      "PROXY_RESIDENTIAL_TRANSFER_GBYTES": 0,
      "PROXY_SERPS": 0
    },
    "usageTotalUsd": 0.00005,
    "usageUsd": {
      "ACTOR_COMPUTE_UNITS": 0,
      "DATASET_READS": 0,
      "DATASET_WRITES": 0,
      "KEY_VALUE_STORE_READS": 0,
      "KEY_VALUE_STORE_WRITES": 0.00005,
      "KEY_VALUE_STORE_LISTS": 0,
      "REQUEST_QUEUE_READS": 0,
      "REQUEST_QUEUE_WRITES": 0,
      "DATA_TRANSFER_INTERNAL_GBYTES": 0,
      "DATA_TRANSFER_EXTERNAL_GBYTES": 0,
      "PROXY_RESIDENTIAL_TRANSFER_GBYTES": 0,
      "PROXY_SERPS": 0
    }
  }
}
```

## Facebook Ads Scraper - Apify Actor

A high-performance Facebook Ads Library scraper built for the Apify platform using Playwright. This actor efficiently scrapes Facebook's Ad Library for ads based on country-keyword pairs with optimized resource usage.

### 🚀 Features

- **High Performance**: Optimized for Apify platform with minimal resource consumption
- **Batch Processing**: Controlled concurrency to prevent memory issues
- **Comprehensive Data**: Extracts detailed ad information including:
  - Ad status and Library ID
  - Page name and start date
  - Primary text and Call-to-Action (CTA)
  - External links and image URLs
  - Raw ad content
- **Robust Error Handling**: Continues processing even if individual ads fail
- **Real-time Output**: Results are saved to Apify dataset immediately

### 📋 Input Schema

The actor accepts the following input parameters:

```json
{
  "targets": [
    {
      "country": "United States",
      "keyword": "rental properties"
    },
    {
      "country": "Canada",
      "keyword": "vacation homes"
    }
  ],
  "adsLimit": 1000,
  "scrollCount": 3,
  "headless": true,
  "maxConcurrency": 1,
  "delay": 2000
}
```

#### Parameters

- **targets** (required): Array of country-keyword pairs to scrape
- **adsLimit** (optional): Maximum ads per target (default: 1000)
- **scrollCount** (optional): Number of scroll actions to load more ads (default: 3)
- **headless** (optional): Run browser in headless mode (default: true)
- **maxConcurrency** (optional): Maximum concurrent browser instances (default: 1)
- **delay** (optional): Delay between actions in milliseconds (default: 2000)

### 📊 Output Format

Each scraped ad contains:

```json
{
  "country": "United States",
  "keyword": "rental properties",
  "ads": [
    {
      "status": "Active",
      "library_id": "123456789",
      "started": "Started running on Jan 1, 2024",
      "page": "Example Page",
      "primary_text": "Find your dream rental property...",
      "cta": "Learn More",
      "links": [
        {
          "type": "link",
          "url": "https://example.com",
          "text": "Visit Website"
        }
      ],
      "image_urls": ["https://example.com/image.jpg"],
      "raw_text": "Full ad text content...",
      "scraped_at": "2024-01-01T12:00:00.000Z"
    }
  ],
  "ads_count": 150,
  "processed_at": "2024-01-01T12:00:00.000Z"
}
```

### 🛠️ Technical Details

#### Architecture

- **Runtime**: Node.js 18 with Playwright
- **Browser**: Chromium with optimized launch arguments
- **Concurrency**: Configurable batch processing
- **Memory**: Optimized for low memory usage on Apify

#### Key Optimizations

- Single browser instance with multiple contexts
- Immediate data saving to prevent loss
- Progressive scroll delays to avoid rate limiting
- Efficient XPath selectors for fast element detection
- Minimal DOM queries with smart caching

#### Error Handling

- Graceful handling of missing elements
- Automatic retry on transient failures
- Detailed error logging for debugging
- Continues processing even if individual ads fail

### 📝 Usage Examples

#### Basic Usage

```json
{
  "targets": [
    {"country": "United States", "keyword": "real estate"},
    {"country": "Canada", "keyword": "homes for sale"}
  ]
}
```

#### Advanced Configuration

```json
{
  "targets": [
    {"country": "United Kingdom", "keyword": "property investment"},
    {"country": "Australia", "keyword": "vacation rentals"}
  ],
  "adsLimit": 500,
  "scrollCount": 5,
  "headless": false,
  "maxConcurrency": 2,
  "delay": 3000
}
```

### ⚠️ Important Notes

1. **Rate Limiting**: The scraper includes delays to respect Facebook's rate limits
2. **Resource Usage**: Optimized for Apify's resource constraints
3. **Data Quality**: Filters out Facebook-internal links and duplicates
4. **Authentication**: Designed to work without login (public Ad Library)

***

Built with ❤️ for the Apify platform
