OneFootball Scraper - News, Fixtures, Results & Standings avatar

OneFootball Scraper - News, Fixtures, Results & Standings

Pricing

from $1.20 / 1,000 result records

Go to Apify Store
OneFootball Scraper - News, Fixtures, Results & Standings

OneFootball Scraper - News, Fixtures, Results & Standings

Scrape public OneFootball data including football news, upcoming fixtures, match results and league tables. Get clean, structured data for teams, competitions and matches in one place.

Pricing

from $1.20 / 1,000 result records

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

1

Bookmarked

1

Total users

1

Monthly active users

6 days ago

Last modified

Categories

Share

OneFootball Scraper: News, Fixtures, Results & League Tables

OneFootball Scraper turns OneFootball into a clean, structured feed of football content. Get news articles, upcoming fixtures, played results with final scores, and league tables for the competitions and teams you choose, or paste your own OneFootball links to read exactly the pages you want. Search by competition and team, or bring your own links, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.

Why This Scraper?

  • Two ways to collect. Search mode walks the competitions, teams and global feed you list; links mode reads exactly the OneFootball pages you paste: competition, team, match or article pages, or the home feed.
  • Three record kinds in one dataset. News articles, match fixtures and results, and league table rows, each labelled by recordType, so one run can feed a news page and a scores widget together.
  • Full article text on demand. Turn on Read full article text to fetch each article's own page and add the complete body. A failed read keeps the feed data and is never billed.
  • Whole seasons, not just a matchday. A competition's fixtures list follows the site's own continuation link to bring in the rest of the season in the same run.
  • Built for schedules. Recurring updates returns only new and changed records on repeat runs, labelled NEW, UPDATED, REAPPEARED, UNCHANGED or EXPIRED. Scores, table numbers and article text are all watched for changes.
  • Resume without repaying. Continue an interrupted run by pasting its run id, and records it already collected are skipped.
  • Honest failures. A run where every page was refused fails loudly instead of returning a quiet empty dataset, and a genuinely empty search says so on the run page instead of guessing.

Use Cases

  • Sports media and newsletters: turn a competition's news feed and results into automated match reports and roundups.
  • Live scores and fixtures widgets: feed a site or app with a team's or competition's upcoming matches and results.
  • Betting and fantasy research: track fixtures, results and league table movement across the competitions a model follows.
  • Season datasets: run on a schedule to build your own archive of results and standings as a season unfolds.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
recordType"news" (also "match", "table")
id"34521987"
title"Sample club confirms new signing ahead of the weekend"
publisher / publisherIsVerified"Sample Publisher" / true
publishedAt"2026-09-20T10:15:00Z"
preview"The club's manager praised the squad depth after completing the deal."
imageUrl"https://onefootball.com/img/sample-news.jpg"
isVideofalse
articleText / articleCharsfull body text / 2450 (only with Read full article text on)
homeTeam / awayTeam"Home Team" / "Away Team" (match)
homeScore / awayScore2 / 1 (match, once played)
kickoff"2026-09-21T15:00:00Z" (match)
status / statusLabel"FULL_TIME" / "Full time" (match)
competitionName"Sample League" (match, table)
teamName"Sample FC" (table)
position / positionChange4 / "UP" (table; see the note below)
played / won / drawn / lost10 / 6 / 2 / 2 (table)
goalDifference / points5 / 20 (table)
url"https://onefootball.com/en/news/sample-club-confirms-new-signing-34521987"
sourceType / sourceId"competition" / "premier-league-9"
changeType / changedFields"UPDATED" / ["homeScore", "status"] (recurring updates only)
firstSeenAt / lastSeenAt"2026-09-14T10:00:00Z" / "2026-09-20T10:15:00Z" (recurring updates only)

Note on position: on every row it is the order in which the actor read the rows on that page (feed order for news and matches). For a normal single league table that equals the rank. It is not the official rank when a page holds several tables (for example World Cup or other group-stage tables, where the count runs on across groups and rows carry no group name) or when the site's ranking skips a number; in those cases do not rely on position as the rank. A team listed in more than one table on the same page appears once. Recurring updates does not compare position, so a rank change on its own is not reported as UPDATED.

A pasted match link (links mode) can additionally carry events (goals, cards and substitutions), lineups, match statistics, a short form guide and the stadium name, when the site's own match page carries them.

How to Use

  1. Pick a mode: search (competitions, teams and the global feed) or your own OneFootball links.
  2. For search mode, list competition slugs and, optionally, team slugs or turn on the global news feed, then switch the four content toggles (News, Fixtures, Results, League table) on or off.
  3. Set Max records (and, if you need a tighter runaway guard, Max pages per source) to control run size and cost, then click Start.
  4. Download the dataset as JSON, CSV or Excel, or read it through the API.

Competitions by slug:

{
"mode": "search",
"competitions": ["premier-league-9", "bundesliga-1"],
"includeNews": true,
"includeFixtures": true,
"includeResults": true,
"includeTable": true,
"maxPages": 1,
"maxItems": 1000
}

One team's news and matches:

{
"mode": "search",
"teams": ["arsenal-2"],
"includeNews": true,
"includeFixtures": true,
"includeResults": true,
"includeTable": false,
"maxItems": 50
}

Global news feed, with full article text:

{
"mode": "search",
"includeGlobalNews": true,
"includeNews": true,
"includeFixtures": false,
"includeResults": false,
"includeTable": false,
"fetchDetails": true,
"maxItems": 20
}

Paste your own links:

{
"mode": "url",
"urls": [
"https://onefootball.com/en/competition/premier-league-9/table",
"https://onefootball.com/en/match/9000001"
]
}

Supported link shapes: home feed (/en/home), competition page, competition fixtures, results and table, team page, team fixtures, results and news sub-pages, match page, news article, localized competition links (/de/competition/..., /es/competicion/...). Links mode never starts empty: the field is prefilled and defaults to one example of each shape.

With the links field left untouched, links mode now reads one example of every supported shape (home feed, competition news, fixtures, results and table, team page with news, fixtures and results sub-pages, match, news article, localized competition links such as /de/ and /es/). Replace the list with your own links to narrow a run. A ?page= parameter is not followed: the link is read from its first page and the run is reported as partial scope.

Copied slugs matter: the number at the end is the site's own id (bundesliga-1 is the German Bundesliga, bundesliga-35 is Liga Portugal). Copy slugs and links from the site rather than typing them from memory.

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/onefootball-com-scraper").call(run_input={
"mode": "search",
"competitions": ["premier-league-9"],
"maxItems": 50,
})
for record in client.dataset(run["defaultDatasetId"]).iterate_items():
print(record["recordType"], record.get("title") or record.get("homeTeam"))

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/onefootball-com-scraper').call({
mode: 'search',
competitions: ['premier-league-9'],
maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

How Max records is spent

Max records (maxItems) is the single cap for the whole run, counting news, matches and table rows together; 0 reads as the highest allowed cap of 100000 records (values above 100000 are read as 100000), and the walk ends earlier when its sources run out. With several competitions or teams listed, the cap is split across the sources still ahead so an early one cannot spend it all. Inside each competition the order is news, then fixtures (the whole remaining season, often a few hundred matches), then results, then the table, and news feeds go deep, so a small cap can be used up before the later kinds are reached (the default of 20 records on one competition returns 20 news articles). Max pages per source (maxPages) bounds how many pages any single news feed reads, about 10 articles per page: set it to 1 or 2 and raise Max records when you want every record kind from each competition, or turn off the kinds you do not need (for example News and Fixtures for results and tables only). 0 reads as deep as the feed goes, up to an internal safety ceiling.

Resume and recurring updates

  • Continue a previous run (resumeFromRunId) finishes ONE interrupted run: paste its run or dataset id and the actor skips every record that run already collected, so you do not pay twice.
  • Recurring updates (incrementalMode) is for running the same setup again and again, for example daily. Each record is classified NEW, UPDATED (with changedFields), UNCHANGED (suppressed and not billed unless emitUnchanged is on), REAPPEARED or EXPIRED (only after a run that read its whole setup end to end, and only with emitExpired on). EXPIRED means the record scrolled out of every source this setup reads, not that it was deleted from the site: results pages, team pages and the global feed show only their latest items, so an older result or article dropping off them is reported as EXPIRED. A capped, resumed or partially failed run never reports records as gone. stateKey names or shares the stored baseline. With Recurring updates off, output is exactly as before.

Filters and sorting

Narrow a run before anything is pushed or billed: dateFrom / dateTo (YYYY-MM-DD, by match kickoff day or news publish day), matchStatus (any, scheduled, live, finished), and query (case-insensitive text match on title, preview, team names or competition). sortBy (site order, date, title) and sortOrder order the rows within each source. League table rows are never narrowed. Filters are part of the incremental baseline scope, so a differently filtered schedule keeps its own baseline.

Dataset views

The dataset has five views on the Output tab: Overview (all kinds), News, Matches, Table and Changes (records labelled by Recurring updates, with changeType and changedFields). Every run also stores an OUTPUT summary record.

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify > Settings > Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where items should be created.

Only news records are sent to connectors; match and table rows stay in the dataset. The connection is mediated by Apify's MCP proxy, so this actor never sees your third party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch (competitions, teams and news feeds) or url (your own links).
competitionsarraysampleCompetition slugs or links to walk (search mode; prefilled with premier-league-9).
teamsarray(none)Team slugs or links to walk (search mode, optional).
includeGlobalNewsbooleanfalseAlso read the site wide front page news feed (search mode).
urlsarrayone link per supported shapeOneFootball links to read exactly as pasted (url mode).
languagestringenContent language. English is the only reliably complete edition.
includeNewsbooleantrueCollect news articles from competitions, teams and the global feed.
includeFixturesbooleantrueCollect upcoming matches from competitions and teams.
includeResultsbooleantrueCollect played matches with final scores.
includeTablebooleantrueCollect league table rows from competitions that have one.
dateFromstring(none)Keep only records on or after this day (YYYY-MM-DD).
dateTostring(none)Keep only records on or before this day (YYYY-MM-DD).
matchStatusstringanyany, scheduled, live or finished.
querystring(none)Case-insensitive text match on title, preview, team names or competition.
sortBystringdefaultOrder rows within each source: site order, date or title.
sortOrderstringascAscending or descending.
fetchDetailsbooleanfalseRead each article's own page and add the full article text.
maxItemsinteger20Stop after this many records across the whole run (0 = the maximum of 100000).
maxPagesinteger0Max pages read per news feed, about 10 articles each (0 = as deep as the feed goes, up to an internal safety ceiling).
resumeFromRunIdstring(none)Continue one interrupted run of this actor.
incrementalModebooleanfalseReturn only new and changed records on recurring runs.
stateKeystring(none)Name or share a recurring updates baseline.
emitUnchangedbooleanfalseAlso return (and bill) unchanged records.
emitExpiredbooleanfalseAlso return (and bill) records that are gone.
ignoreFieldsForChangesstring listemptyField names that do not count as a change in Recurring updates (the field is still returned). Use a dotted name such as homeTeam.name for a nested field.
mcpConnectorsarray(none)Optional: send a summary of each news record to apps you authorized under Integrations.
notionParentPageUrlstring(none)Notion connector only: page under which item pages are created.
maxNotifyListingsinteger50Cap on items written to each connector per run.
proxyConfigurationobjectApify ProxyConnection used for every request.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"recordType": "news",
"id": "34521987",
"title": "Sample club confirms new signing ahead of the weekend",
"url": "https://onefootball.com/en/news/sample-club-confirms-new-signing-34521987",
"publisher": "Sample Publisher",
"publisherIsVerified": true,
"publishedAt": "2026-09-20T10:15:00Z",
"preview": "The club's manager praised the squad depth after completing the deal.",
"imageUrl": "https://onefootball.com/img/sample-news.jpg",
"isVideo": false,
"language": "en",
"articleText": "Sample paragraph one of the article body, for illustration only.\n\nSample paragraph two continuing the illustrative body text.",
"articleChars": 130,
"sourceType": "competition",
"sourceId": "premier-league-9",
"sourceUrl": "https://onefootball.com/en/competition/premier-league-9",
"position": 3,
"scrapedAt": "2026-09-20T10:20:00Z"
}

Plan Requirement

The default connection (Apify Proxy, standard datacenter pool) is enough: OneFootball's pages and content API answered plain requests without a challenge in our live checks, so no residential proxy is required. If the standard pool is refused for your account, the run tries backup connections and says so on the run page ("Served over the backup connection (the default connection was unavailable)."). On a free Apify plan, where residential proxies are not included, you may see "Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable."

If no page could be loaded the run fails with one of three messages: the proxy connection was refused for your account (a paid plan is required, or check your own proxy URLs); "No results: residential proxies are unavailable on this run ... and the backup connection could not load the requested OneFootball pages"; or "Could not load any results page (the requests failed) ... This is a connection problem, not an empty search." Switch under Connection only if you want to paste your own proxy links, for example for a specific exit country.

FAQ

How much does it cost?

Billing is pay per event, as shown on the Pricing tab: one charge per record pushed to the dataset (apify-default-dataset-item), one detail-enrichment charge per article whose full text was read with Read full article text on, and the usual apify-actor-start charge per run. Unchanged, filtered-out and failed records are never charged. Use Max records to cap a run.

This actor collects only publicly available football content. You are responsible for how you use it: follow OneFootball's terms and the laws that apply to you, and get legal advice before any commercial redistribution. Scores and fixtures are generally facts, but article text, logos and photos may carry their own publisher or image rights.

Can I get only new or changed records on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Recurring updates. Each run then returns only NEW, UPDATED and REAPPEARED records, and unchanged ones are skipped and not billed unless you turn that on too.

What is the difference between "Continue a previous run" and "Recurring updates"?

They solve different problems. Continue a previous run (resumeFromRunId) finishes ONE run that was interrupted, skipping records it already collected. Recurring updates (incrementalMode) is for running the same setup again and again on a schedule, comparing against last time. Turning both on for the same setup fails the run with a message asking you to pick one.

Why did a competition return nothing, or the wrong league?

Slugs carry the site's own id, and it is not guessable: bundesliga-1 is the German Bundesliga, bundesliga-35 is Liga Portugal. Copy the slug, or the whole link, from the competition's own page on OneFootball rather than typing one from memory. A slug that does not exist fails that one source loud, with the rest of the run unaffected.

Why did my run fail instead of returning an empty dataset?

If every page the run tried was refused, the run stops with a clear message so a genuinely quiet news day is never confused with a connection problem. Run it again in a few minutes. If only some competitions, teams or links could be read, you still get what was found, with a note on the run page.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

šŸ”— Want more sports data?

Pair this actor with these related scrapers from the same team:

⚽ Globo Esporte Scraper
Scrape public sports content from ge.globo.com, including news, videos, matches and feed...
⚽ FotMob Scraper ⚽ Match Details, Stats, Lineups & Players
Pull structured football data from FotMob: match details with scores, team stats, events...
⚽ SofaScore Scraper ⚽ Live Scores, Stats, Players & Odds
Pull structured sports data from SofaScore across football, basketball, tennis, and 20+...
⚽ Sportsbook Odds Scraper (1xBet, Melbet, Linebet, Paripulse)
Collect live and prematch betting odds from 1xBet, Melbet, Linebet and Paripulse. Give it...
⚽ Whatnot Scraper
Scrape Whatnot live and upcoming shows, queued items and lots, and seller profiles...
⚽ BookMyShow Scraper
Scrape BookMyShow movies and live events by city, category or URL. Extract genres...

šŸ‘‰ Browse all abotapi scrapers

šŸ’¬ Support

  • šŸž Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • šŸ› ļø Need another site, extra fields or a private build? Email contact@abotapi.com.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.