
Website Content Crawler
scrape.ly/store/querystone/website-content-crawlerAIDeveloper tools
4 monthly users

Odds from every bookmaker on OddsPortal: upcoming fixtures, results archives with closing odds, scores, best and average prices, payouts and optional full market books with opening and closing odds. Any sport. No login needed.
Export odds from every bookmaker on OddsPortal as JSON, CSV or Excel: upcoming fixtures with current prices, results archives with final scores and closing odds, and, on request, the full market book with opening and closing odds for every match. Paste a league link and get one clean row per match in seconds. No login, no API key, and a price per match well below comparable tools.
https://www.oddsportal.com/football/england/premier-league/ for upcoming fixtures;results/ added for finished matches of the current season;https://www.oddsportal.com/football/spain/laliga-2024-2025/results/ for an older season (pick the season on the site's results page and copy the link);# and the match id) for one match.| Field | What it does |
|---|---|
League or match URLs (startUrls) | OddsPortal league, results, season or match links. Any sport. |
Max matches (maxItems) | Maximum matches across all links. Default 20; 0 means no limit. |
Scrape all betting markets (scrapeMatchMarkets) | Adds the full market book of each match with opening and closing odds. Default off. |
Markets to include (marketTypes) | Only these markets in the market book, e.g. ["Over/Under", "Asian Handicap"]. Empty means all. |
Full time only (mainPeriodOnly) | Market book without halves, quarters, periods or sets. |
Proxy configuration (proxyConfiguration) | Its country decides which bookmakers OddsPortal lists. Residential Malta (default) gives the widest international list. |
{
"startUrls": [
{ "url": "https://www.oddsportal.com/football/england/premier-league/" },
{ "url": "https://www.oddsportal.com/football/spain/laliga-2024-2025/results/" }
],
"maxItems": 200,
"scrapeMatchMarkets": false
}
One row per match:
| Field | Description |
|---|---|
matchId, eventId, url | OddsPortal match number, match id and match link |
sport, country, league, leagueUrl, season | Where the match belongs (season is set for results pages) |
homeTeam, awayTeam, homeTeamUrl, awayTeamUrl | Teams or players and their pages |
startTime, startTimestamp | Start time in UTC (ISO 8601 and Unix seconds) |
status, isFinished | Scheduled, Finished, Postponed, Canceled... |
result, homeScore, awayScore, partialResult, winner | Final score, period scores and the winner (home, away or draw) |
venue, venueTown, venueCountry | Where the match is played |
odds | Average and best price per outcome, the bookmaker with the best price and the bookmaker count |
avgHomeOdds, avgDrawOdds, avgAwayOdds, bestHomeOdds, bestDrawOdds, bestAwayOdds | The same prices as flat columns for spreadsheets |
bookmakerOdds | Every bookmaker's own match-winner prices and payout percentage |
bookmakerCount | Number of bookmakers with match-winner odds |
markets | With Scrape all betting markets: one entry per market, period and line, with closing odds, opening odds and opening time per bookmaker |
scrapedAt | When the row was saved |
A finished LaLiga match from a test run, with bookmakerOdds trimmed to 3 of 11 bookmakers and markets to one line:
{
"matchId": 7722277,
"eventId": "4xBMgyvp",
"url": "https://www.oddsportal.com/football/h2h/ath-bilbao-IP5zl0cJ/barcelona-SKbpVP5K/#4xBMgyvp",
"sport": "Football",
"country": "Spain",
"league": "LaLiga 2024/2025",
"leagueUrl": "https://www.oddsportal.com/football/spain/laliga-2024-2025/",
"season": "2024/2025",
"homeTeam": "Ath Bilbao",
"awayTeam": "Barcelona",
"homeTeamUrl": "https://www.oddsportal.com/football/team/ath-bilbao/IP5zl0cJ/",
"awayTeamUrl": "https://www.oddsportal.com/football/team/barcelona/SKbpVP5K/",
"startTime": "2025-05-25T19:00:00.000Z",
"startTimestamp": 1748199600,
"status": "Finished",
"isFinished": true,
"result": "0:3",
"homeScore": 0,
"awayScore": 3,
"partialResult": "0:2, 0:1",
"winner": "away",
"venue": "Estadio San Mamés",
"venueTown": "Bilbao",
"venueCountry": "Spain",
"bookmakerCount": 11,
"odds": {
"home": { "average": 3.28, "highest": 3.49, "highestBookmaker": "1xBet", "bookmakerCount": 11 },
"draw": { "average": 3.92, "highest": 4.04, "highestBookmaker": "GGBET", "bookmakerCount": 11 },
"away": { "average": 2.08, "highest": 2.15, "highestBookmaker": "Betsson", "bookmakerCount": 11 }
},
"bookmakerOdds": [
{ "bookmakerId": 3, "bookmaker": "bet-at-home", "payout": 94.2, "home": 3.1, "draw": 3.8, "away": 2.1 },
{ "bookmakerId": 16, "bookmaker": "bet365", "payout": 94.6, "home": 3.2, "draw": 3.9, "away": 2.05 },
{ "bookmakerId": 43, "bookmaker": "Betsson", "payout": 95.8, "home": 3.2, "draw": 3.75, "away": 2.15 }
],
"avgHomeOdds": 3.28,
"bestHomeOdds": 3.49,
"avgDrawOdds": 3.92,
"bestDrawOdds": 4.04,
"avgAwayOdds": 2.08,
"bestAwayOdds": 2.15,
"markets": [
{
"market": "Over/Under",
"marketId": 2,
"scope": "Full Time",
"scopeId": 2,
"handicap": 2.5,
"bookmakers": [
{
"bookmakerId": 16,
"bookmaker": "bet365",
"closingOdds": { "over": 1.44, "under": 2.75 },
"openingOdds": { "over": 1.62, "under": 2.3 },
"openingTime": { "over": "2025-05-19T08:37:30.000Z", "under": "2025-05-19T08:37:30.000Z" }
}
]
}
],
"scrapedAt": "2026-10-22T03:43:21.738Z"
}
Two-way sports (tennis, basketball, baseball...) have home and away prices only. Correct Score and HT/FT lines carry the score in handicap (e.g. "1:0", "1/1") and one odds price per bookmaker. For upcoming matches closingOdds holds the current price.
Pay per result, no monthly rental:
Examples:
Platform usage (compute and residential proxy traffic) is billed on top and is small: about $0.001 for a 380-match season in our tests, and about $0.30 per 1,000 matches with market books.
Is it legal to scrape OddsPortal? The scraper reads only publicly visible pages and stores no personal data. Check OddsPortal's terms and the rules that apply to you before using the data; ask a lawyer if you are unsure.
Do I need an account, cookies or my own proxy? No. The run uses residential exits in Malta by default, which shows the widest international bookmaker list. Pick another country in the proxy settings to see that country's licensed bookmakers instead (datacenter exits are in the US and show US sportsbooks only).
How many matches can I get? As many as the links list. A results or season link is read page by page to the end of the season (OddsPortal shows 50 matches per page). A plain league link lists only the upcoming fixtures the league page shows right now. Set Max matches to 0 for no limit.
How far back does the history go? As far as OddsPortal has seasons for the league: add one season link per season. Older seasons usually list fewer bookmakers.
Why is a field empty? Upcoming matches have no result, winner or scores yet, some matches have no odds at all (odds is null), and some matches have no market odds (markets is empty and the market book is not charged).
Can I schedule it or use it through the API? Yes. Schedule runs on upcoming-fixture links to record your own odds history, and start runs or read datasets through the API with any HTTP client.
Every field below can be set in the run form, passed through the API, or saved as a task. Unset fields fall back to the defaults shown.
startUrlsarrayRequiredLeague or match URLs
OddsPortal links to scrape. A league link (e.g. https://www.oddsportal.com/football/england/premier-league/) returns the upcoming fixtures with odds. Add results/ for finished matches with scores and closing odds, or use a season link such as https://www.oddsportal.com/football/spain/laliga-2024-2025/results/ for older seasons (every page of the season is read). A match link (it ends with #) returns that one match. Every sport on the site works.
maxItemsintegerOptionaldefault 20Max matches
Maximum number of matches to return across all links. 0 means no limit (a whole results season is read page by page).
Optional: every betting market of each match, with opening and closing odds per bookmaker.
scrapeMatchMarketsbooleanOptionaldefault falseScrape all betting markets
Also collect the full market book of every match: Over/Under, Asian Handicap, Correct Score, Both Teams to Score, Double Chance, Draw No Bet, Half Time / Full Time, European Handicap and more, for every period, with opening and closing odds per bookmaker. Slower, and billed as a separate event only for matches that have market odds.
marketTypesarrayOptionalMarkets to include
Only these markets in the market book. Leave empty for every market. Only used when 'Scrape all betting markets' is on.
mainPeriodOnlybooleanOptionaldefault falseFull time only
Only the full-time markets (Full Time and FT including OT), without halves, quarters, periods or sets. Faster. Only used when 'Scrape all betting markets' is on.
proxyConfigurationobjectOptionaldefault {"useScrapelyProxy":true,"scrapelyProxyGroups":["RESIDENTIA…Proxy configuration
The proxy country decides which bookmakers OddsPortal lists. Residential Malta (the default) shows the widest international selection (17 bookmakers on Premier League matches in our tests, including bet365, 1xBet, Betsson and Stake.com). Another country shows that country's licensed bookmakers instead, e.g. GB or DE. Datacenter exits are in the US and show only US sportsbooks.
Every run writes its results to a dataset. Preview it in the dashboard, then export it or read it through the API.
| Field | Type | Description |
|---|---|---|
| matchId | number | null | OddsPortal match number |
| eventId | string | null | OddsPortal match id (the part after # in the match link) |
| url | string | null | Match page |
| sport | string | null | Sport |
| country | string | null | Country or region |
| league | string | null | League or tournament (with season for past seasons) |
| leagueUrl | string | null | League page |
| season | string | null | Season of a results page, e.g. 2024/2025 |
| homeTeam | string | null | Home team or first player |
| awayTeam | string | null | Away team or second player |
| homeTeamUrl | string | null | Home team page |
| awayTeamUrl | string | null | Away team page |
| startTime | string | null | Start time (UTC, ISO 8601) |
| startTimestamp | number | null | Start time (Unix seconds) |
| status | string | null | Scheduled, Finished, Postponed, Canceled... |
| isFinished | boolean | null | True for finished matches |
| result | string | null | Final score, e.g. 2:1 |
| homeScore | number | null | Home final score |
| awayScore | number | null | Away final score |
| partialResult | string | null | Period scores, e.g. 1:0, 1:1 |
| winner | string | null | home, away or draw |
| venue | string | null | Stadium or arena |
| venueTown | string | null | Venue town |
| venueCountry | string | null | Venue country |
| bookmakerCount | number | null | Bookmakers with match-winner odds |
| avgHomeOdds | number | null | Average home odds |
| avgDrawOdds | number | null | Average draw odds (3-way sports) |
| avgAwayOdds | number | null | Average away odds |
| bestHomeOdds | number | null | Best home odds |
| bestDrawOdds | number | null | Best draw odds (3-way sports) |
| bestAwayOdds | number | null | Best away odds |
| odds | object | null | Average and best price per outcome, the bookmaker with the best price and the bookmaker count |
| bookmakerOdds | array | null | Every bookmaker's match-winner odds and payout percentage |
| markets | array | null | Full market book (with 'Scrape all betting markets'): one entry per market, period and line with opening and closing odds per bookmaker |
| scrapedAt | string | null | When the row was saved (UTC) |
You pay for the events the actor reports, such as each result or page it produces. Platform usage is included in the event prices.
| Event | Charged when | Price |
|---|---|---|
| Match with odds | Charged for each match saved: a fixture or finished match with every bookmaker's match-winner odds, best and average prices, payouts and the score. Invalid links and empty leagues are free. | $0.002 |
| Full market book | Charged per match only with 'Scrape all betting markets' on and only when market odds came back: every market, period and line with opening and closing odds per bookmaker. | $0.014 |
Run this actor from your own code. Swap in your API token and the examples work as-is.
import { ScrapelyClient } from 'scrapely-client'
const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN })
// Start the actor and wait for the run to finish.
const run = await client.actor('querystone/oddsportal-scraper').call({
"startUrls": [
{
"url": "https://www.oddsportal.com/football/england/premier-league/"
}
],
"maxItems": 20,
"proxyConfiguration": {
"useScrapelyProxy": true,
"scrapelyProxyGroups": [
"RESIDENTIAL"
],
"scrapelyProxyCountry": "MT"
}
})
// Read the dataset the run produced.
const { items } = await client.dataset(run.defaultDatasetId).listItems()
console.log(items)Tokens live in your account settings. Keep them server-side: a token carries the full permissions of your account.
Connect the Scrape.ly MCP server once and your agent can run this actor as a tool. Pick your tool:
Fetch scrape.ly/agents.md and run querystone/oddsportal-scraperPaste into Claude Code, Codex, Cursor or any AI agent. It signs you in once in the browser.
{
"mcpServers": {
"scrapely": {
"url": "https://api.scrape.ly/mcp?tools=actors,runs,storage,docs&actors=querystone/oddsportal-scraper"
}
}
}No key in the file: your client opens the browser to sign you in the first time it connects.
No examples yet
The developer hasn't published example inputs for this actor.

Scrape Google Maps places for any search term and city, with no code or with one API call. A real run, its output, its log and its exact cost, plus the limits and the legal side.
Read the article
Paste an Amazon search or product URL into a ready-made Actor and get one row per product with price, ASIN, rating and review count. This guide covers the no-code steps, the API, ZIP code pricing, a real run and its cost.
Read the article
Scrape Google search results by query and country and get each results page as JSON: organic results with positions, People Also Ask and related searches. Run it without code or from Python, with a real run, the cost per page and Google's terms.
Read the articleScrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.