# BetExplorer Scraper (`piotrv1001/betexplorer-scraper`) Actor

The BetExplorer Scraper extracts fixtures, results and betting odds from BetExplorer.com, capturing kick-off times, teams, final scores, average odds and every bookmaker's own price with timestamps across all markets - ideal for betting models and odds backtesting.

- **URL**: https://apify.com/piotrv1001/betexplorer-scraper.md
- **Developed by:** [FalconScrape](https://apify.com/piotrv1001) (community)
- **Categories:** Automation, Developer tools, Other
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 matches

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 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

### 🚀 BetExplorer Scraper

Extract **fixtures, results and betting odds** from [BetExplorer.com](https://www.betexplorer.com) in structured JSON. The **BetExplorer Scraper** returns a whole season in a single request — every match with its final score and average odds — and, when you ask for it, **every bookmaker's individual price with its own timestamp** across every market the sport offers.

Paste a league URL, hit run, and get a clean dataset. Running it on Apify also gives you scheduled runs, an API, webhooks, integrations with Google Sheets, Zapier and Make, automatic proxy rotation, and run monitoring — no infrastructure to maintain.

### ✨ Features

- 📅 **Fixtures and results in one place** — kick-off times, teams, rounds, final scores, winners and average 1X2 odds.
- 🏦 **Every bookmaker, not just the average** — up to 20 bookmakers per match, each with its own price and the exact minute that price was last moved.
- 🎯 **Every market the sport offers** — 1X2, Over/Under, Asian Handicap, Draw No Bet, Double Chance and Both Teams To Score, with all handicap and total lines. Over 500 individual prices for a single football match.
- 📚 **Deep historical archive** — one season per URL, going back to the earliest season BetExplorer keeps for the competition (over a century for some leagues).
- 🏅 **Seven sports** — football, tennis, basketball, hockey, baseball, handball and volleyball. Any league page works.
- 🌍 **Choose your bookmaker region** — the proxy country decides which bookmakers you see; the default returns the widest international selection.
- ⚡ **Fast and lightweight** — a full 380-match season arrives in one request, no browser required.

### 💡 Why use the BetExplorer Scraper?

- **Build and backtest betting models** on decades of results paired with the odds that were actually on offer.
- **Find value and arbitrage** by comparing every bookmaker's price on the same market side by side.
- **Measure closing line value (CLV)** using the per-price timestamps returned with every bookmaker quote.
- **Power odds-comparison sites and dashboards** with a scheduled feed of upcoming fixtures.
- **Feed sports analytics and prediction tools** with a consistent, structured match history across seven sports.

### 🛠️ How to use the BetExplorer Scraper

1. **Pick your league URLs.** Copy a league page from BetExplorer, e.g. `https://www.betexplorer.com/football/england/premier-league/`. A plain league URL returns both finished results and upcoming fixtures; add `/results/` or `/fixtures/` to pick one. Use a season URL such as `https://www.betexplorer.com/football/england/premier-league-2025-2026/results/` for history.
2. **Set the match limit.** `maxItems` caps how many matches you get across all URLs.
3. **Optionally enable the full odds book.** Turn on `scrapeOdds` if you need every bookmaker's price rather than the average.
4. **Run it.** Results appear in the dataset and can be downloaded as JSON, CSV, Excel, HTML or XML, or pulled from the API.

### 📥 Input

| Field | Type | Description |
|---|---|---|
| `startUrls` | array | BetExplorer league URLs. Plain league URL → results *and* fixtures. `/results/` or `/fixtures/` → just that list. Season URLs return the whole season. |
| `maxItems` | integer | Maximum number of matches to return across all start URLs. Default `50`. |
| `scrapeOdds` | boolean | Also collect every bookmaker's odds across every market for each match. Slower and billed separately. Default `false`. |
| `proxyConfiguration` | object | Proxy for the run. The **proxy country decides which bookmakers appear** — Malta (default) gives the widest international list; UK, Germany, Brazil or US return that country's licensed bookmakers. |

Example input:

```json
{
    "startUrls": [
        { "url": "https://www.betexplorer.com/football/england/premier-league/" },
        { "url": "https://www.betexplorer.com/football/spain/laliga-2025-2026/results/" }
    ],
    "maxItems": 200,
    "scrapeOdds": false,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "MT"
    }
}
```

### 📊 Sample output data

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

```json
[
    {
        "matchId": "xQXUa3UG",
        "url": "https://www.betexplorer.com/football/england/premier-league-2025-2026/brighton-manchester-united/xQXUa3UG/",
        "sport": "Football",
        "country": "England",
        "league": "Premier League",
        "season": "2025/2026",
        "round": "38. Round",
        "startTime": "2026-05-23T22:00:00.000Z",
        "homeTeam": "Brighton",
        "awayTeam": "Manchester Utd",
        "status": "FINISHED",
        "score": "0:3",
        "homeScore": 0,
        "awayScore": 3,
        "winner": "AWAY",
        "bookmakerCount": 20,
        "averageOdds": { "1": 1.88, "X": 4.14, "2": 3.46 }
    }
]
```

With `scrapeOdds` enabled, each match additionally carries an `odds` array — one entry per market, each holding every bookmaker's price:

```json
{
    "odds": [
        {
            "market": "1X2",
            "prices": [
                {
                    "bookmaker": "bet365",
                    "outcomes": [
                        { "label": "1", "odd": 1.86, "updatedAt": "2026-05-24T14:55:00.000Z" },
                        { "label": "X", "odd": 4.0, "updatedAt": "2026-05-24T14:50:00.000Z" },
                        { "label": "2", "odd": 3.43, "updatedAt": "2026-05-24T14:55:00.000Z" }
                    ]
                }
            ]
        },
        {
            "market": "Over/Under",
            "prices": [
                {
                    "bookmaker": "Pinnacle",
                    "handicap": "2.5",
                    "outcomes": [
                        { "label": "Over", "odd": 1.97, "updatedAt": "2026-05-24T14:40:00.000Z" },
                        { "label": "Under", "odd": 1.91, "updatedAt": "2026-05-24T14:40:00.000Z" }
                    ]
                }
            ]
        }
    ]
}
```

### 📋 Data fields

| Field | Description |
|---|---|
| `matchId` | BetExplorer's identifier for the match |
| `url` | Link to the match page |
| `sport`, `country`, `league`, `season` | Competition the match belongs to |
| `round` | Round or matchday, when the competition has one |
| `startTime` | Kick-off in ISO 8601 (UTC) |
| `homeTeam`, `awayTeam` | The two teams or players |
| `status` | `FINISHED` or `SCHEDULED` |
| `score`, `homeScore`, `awayScore`, `winner` | Final score and `HOME` / `DRAW` / `AWAY` |
| `bookmakerCount` | How many bookmakers priced the match |
| `averageOdds` | Average odds per outcome, keyed by the market's own labels (`1`, `X`, `2`) |
| `odds` | Every market, every bookmaker, every price with its own timestamp (only when `scrapeOdds` is on) |

### 💰 How much does it cost to scrape BetExplorer?

The scraper uses **pay per event** pricing, so you only pay for the data you actually get:

| Event | Price | What it covers |
|---|---|---|
| Actor start | $0.005 | Charged once per run |
| Match | $0.003 | One fixture or result with score and average odds |
| Match with full odds book | $0.008 | The same match plus every bookmaker's price across every market (only when `scrapeOdds` is on) |

A full league sweep of **380 finished matches costs about $1.15**. The same 380 matches with every bookmaker's odds included costs around $3.05. Apify's free tier includes $5 of monthly usage, enough to try the scraper on several full seasons.

### ⚙️ Tips and advanced options

- **Leave `scrapeOdds` off** unless you need individual bookmaker prices — the average odds already come free with every match, and the full book is several requests per match.
- **Season URLs are the cheapest way to build history.** Open any league's results page, use the season dropdown to copy a season's URL, and add those URLs to `startUrls`.
- **Bookmaker coverage depends on the proxy country.** Malta, Australia and India return the widest international list; a UK proxy returns UK-licensed books, a Brazilian proxy Brazilian ones. Datacenter proxies return only a small US selection, so residential is recommended.
- **Older seasons have fewer bookmakers.** Results reach back a very long way, but multi-bookmaker odds realistically start in the late 2000s.
- **Schedule it.** Run it daily against fixture URLs to build your own odds-movement history over time.

### ❓ FAQ

**Which sports are supported?**
Football, tennis, basketball, hockey, baseball, handball and volleyball. Any league page on BetExplorer works, and the scraper reads the available markets from the page, so sport-specific markets (like Home/Away instead of 1X2 in tennis) come through automatically.

**How far back does the historical data go?**
As far as BetExplorer's own archive — over a century of seasons for some leagues. Add one season URL per season you want.

**Why do I see different bookmakers than on the website?**
BetExplorer shows different bookmakers depending on where you connect from. Change `apifyProxyCountry` in the proxy settings to target a specific market.

**Do I get the time each price was set?**
Yes. With `scrapeOdds` enabled, every bookmaker price carries the timestamp of its last movement, which is what closing-line-value analysis needs.

**Is scraping BetExplorer legal?**
The scraper only collects publicly available data and stores no personal information, and it stays within the paths BetExplorer's `robots.txt` allows. Their Terms of Service still apply to you as the operator of the run, so you are responsible for making sure your use complies with applicable law and terms — consult a lawyer if you are unsure.

**Something is broken or missing.**
Open an issue on the Actor's **Issues** tab and it will be looked at. Custom variants and bulk extractions can also be arranged.

Start extracting BetExplorer odds today! 🚀

# Actor input Schema

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

BetExplorer league pages to scrape. A plain league URL returns both the finished results and the upcoming fixtures; add `/results/` or `/fixtures/` to pick one. Season URLs such as `https://www.betexplorer.com/football/england/premier-league-2025-2026/results/` return that whole season, as far back as the site's archive goes. Works for football, tennis, basketball, hockey, baseball, handball and volleyball.

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

Maximum number of matches to return across all start URLs.

## `scrapeOdds` (type: `boolean`):

Also collect the full odds book for each match - every bookmaker's price with its own timestamp, across every market the sport offers (1X2, Over/Under, Asian Handicap, Draw No Bet, Double Chance, Both Teams To Score). Much slower and billed separately - leave off if the average odds in the listing are enough.

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

Proxy used for the run. The proxy country decides which bookmakers are returned: Malta (the default) gives the widest international selection, while UK, Germany, Brazil or US return that country's licensed bookmakers instead.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.betexplorer.com/football/england/premier-league/"
    }
  ],
  "maxItems": 50,
  "scrapeOdds": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "MT"
  }
}
```

# Actor output Schema

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

No description

# 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.betexplorer.com/football/england/premier-league/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("piotrv1001/betexplorer-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.betexplorer.com/football/england/premier-league/" }] }

# Run the Actor and wait for it to finish
run = client.actor("piotrv1001/betexplorer-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 '{
  "startUrls": [
    {
      "url": "https://www.betexplorer.com/football/england/premier-league/"
    }
  ]
}' |
apify call piotrv1001/betexplorer-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,piotrv1001/betexplorer-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/x5yz7lCkYHlwkfURt/builds/7liIVUwQ774jkYhuq/openapi.json
