- Что такое виджет статистики матча и какие данные он показывает
- Как выбрать API спортивных событий для виджета статистики матча
- Как получать статистику футбольного матча через API на JavaScript
- Структура данных матча из API и подготовка к отображению в виджете
- Пример кода JavaScript для виджета статистики матча с HTML и CSS
- Как сделать обновление статистики матча в реальном времени через API
- Интеграция виджета статистики матча на сайт и типичные ошибки при работе с API
Что такое виджет статистики матча и какие данные он показывает
Виджет статистики матча на JavaScript — это интерактивный блок, который встраивается на сайт и показывает ключевые показатели игры в удобном визуальном формате. Такой виджет работает поверх API спортивных событий, получает сырые данные о матче и преобразует их в понятные пользователю таблицы, графики, индикаторы владения мячом и временные линии событий.
На базе API Sport Events можно отобразить практически любую метрику: счет по таймам, текущую минуту встречи, составы команд, подробную статистику ударов, владения мячом, единоборств, фолов, карточек и угловых. Дополнительно доступны live-события (голы, замены, карточки, VAR), а также расширенные блоки вроде xG-метрик, видеообзоров и хайлайтов матча, если они присутствуют в источнике. Для букмекеров и аналитических сервисов важно и то, что через тот же API можно показывать коэффициенты на исходы и тоталы, а также динамику изменения линий.
Грамотно реализованный виджет статистики становится точкой удержания аудитории: на спортивном медиа он увеличивает глубину просмотра, на сайте букмекера помогает игроку принять решение по ставке, а в фанатском сообществе или в блоге — делает контент живым и «игровым». Используя готовый API вроде сервиса api-sport.ru, можно быстро получать детальные данные по футболу, баскетболу, хоккею, теннису, настольному теннису, киберспорту и другим видам спорта и выводить их в едином унифицированном интерфейсе виджета.
Как выбрать API спортивных событий для виджета статистики матча
Первый шаг к созданию стабильного виджета — выбор надежного поставщика данных. Важно, чтобы API охватывал нужные виды спорта и турниры. В Sport Events API это решается через эндпоинт /v2/sport, который возвращает список поддерживаемых видов спорта (футбол, хоккей, баскетбол, теннис, настольный теннис, киберспорт и другие). Далее через категории и турниры вы выбираете конкретные чемпионаты, которые будут доступны в вашем виджете, используя, например, методы /v2/{sportSlug}/categories и /v2/{sportSlug}/categories/{categoryId} с учетом поля defaultTournaments.
Не менее важны глубина и структура статистики. Современный виджет должен уметь показывать не только счет, но и расширенные показатели. В Sport Events API объект матча содержит поля matchStatistics с разбиением по периодам и группам («Match overview», «Shots», «Duels» и т. д.), а также liveEvents для показа таймлайна событий. Для беттинг-проектов критично наличие поля oddsBase, которое возвращает рынки ставок и коэффициенты (включая live), а также история их изменения. Все это позволяет строить как простые, так и продвинутые виджеты на одном и том же API.
Отдельно стоит оценить технические характеристики: стабильность доступности, скорость ответа, честные ограничения по запросам, понятную документацию и наличие примеров кода. Платформа API спортивных событий api-sport.ru ориентирована на разработчиков: она предлагает детальное OpenAPI-описание, регулярно расширяет набор видов спорта и полей, а в ближайшее время дополнит REST-интерфейс WebSocket-стримом для обновления статистики в реальном времени и AI-инструментами для аналитики. Это упрощает масштабирование проекта и добавление новых видов спорта без полного переписывания виджета.
Как получать статистику футбольного матча через API на JavaScript
Чтобы начать работать с данными, вам нужен API-ключ. В экосистеме api-sport.ru он выдается в личном кабинете разработчика. После регистрации перейдите в личный кабинет, сгенерируйте ключ и используйте его в заголовке Authorization для всех запросов к REST-эндпоинтам. Без корректного ключа сервер вернет ошибку авторизации и данные матча будут недоступны.
Базовый сценарий получения статистики футбольного матча на JavaScript выглядит так: вы знаете идентификатор матча (matchId) и вид спорта (football). Далее отправляете GET-запрос к методу /v2/football/matches/{matchId} на хосте API. В ответ получаете объект Match со всеми полями: статус, счет, команды, подробные matchStatistics, массив liveEvents, а при необходимости и коэффициенты oddsBase. Ниже — пример простого запроса с использованием fetch в браузере.
const API_KEY = 'YOUR_API_KEY';
const MATCH_ID = 14570728; // пример ID матча
async function loadMatchStatistics() {
const response = await fetch(
`https://api.api-sport.ru/v2/football/matches/${MATCH_ID}`,
{
headers: {
'Authorization': API_KEY
}
}
);
if (!response.ok) {
throw new Error('Ошибка API: ' + response.status);
}
const match = await response.json();
console.log('Команды:', match.homeTeam.name, '—', match.awayTeam.name);
console.log('Текущий счет:', match.homeScore.current, ':', match.awayScore.current);
console.log('Статистика матча:', match.matchStatistics);
}
loadMatchStatistics().catch(console.error);
На практике этот код вы будете вызывать не в консоль, а внутри логики виджета, передавая объект match в функцию рендера. Важно предусмотреть обработку ошибок (например, недоступность матча или сетевые проблемы), а также проверить статус поля status (например, inprogress, finished, notstarted) и корректно отобразить состояние игры в интерфейсе.
Структура данных матча из API и подготовка к отображению в виджете
Ответ эндпоинта /v2/{sportSlug}/matches/{matchId} строится вокруг объекта Match. В нем содержатся базовые поля (id, status, dateEvent, startTimestamp), информация о турнире и сезоне, данные о стадионе (venue), а также вложенные объекты команд homeTeam и awayTeam с их названиями, логотипами и, при необходимости, составах (lineup). Текущий и промежуточный счет хранится в объектах homeScore и awayScore с полями current, period1, period2 и аналогичными для других видов спорта.
Ключевой элемент для виджета статистики — массив matchStatistics. Он разбит на периоды (period: ALL, 1ST, 2ND и т. д.). Внутри каждого периода есть массив groups, а в нем — массив statisticsItems с конкретными показателями. Каждый элемент содержит название метрики (name), значения для хозяев и гостей (home, away), числовые значения (homeValue, awayValue) и служебный ключ key, по которому удобно маппить метрику на нужный UI-блок. Ниже упрощенный фрагмент ответа:
// Фрагмент JSON-ответа матча
{
id: 14570728,
status: 'inprogress',
currentMatchMinute: 30,
homeTeam: { id: 195801, name: 'Montevideo Wanderers Reserve' },
awayTeam: { id: 195800, name: 'Rival Team' },
homeScore: { current: 1, period1: 1, period2: 0 },
awayScore: { current: 0, period1: 0, period2: 0 },
matchStatistics: [
{
period: 'ALL',
groups: [
{
groupName: 'Match overview',
statisticsItems: [
{
name: 'Ball possession',
home: '54%',
away: '46%',
key: 'ballPossession'
}
]
}
]
}
]
}
Перед выводом в виджете имеет смысл нормализовать структуру в более удобный формат. Например, можно построить словарь по ключам статистики: { ballPossession: { home: 54, away: 46 }, totalShotsOnGoal: { ... } }. Это упростит рендер прогресс-баров, диаграмм и сравнительных таблиц. Если вы планируете показывать также коэффициенты и видеообзоры, заранее выделите из объекта матча поля oddsBase и highlights, чтобы подгружать их в отдельные вкладки виджета или всплывающие окна.
Пример кода JavaScript для виджета статистики матча с HTML и CSS
Ниже приведен упрощенный, но рабочий пример мини-виджета статистики футбольного матча. Он включает базовую HTML-разметку, минимальный CSS для оформления и JavaScript-код, который загружает данные из Sport Events API и заполняет блок виджета. В реальном проекте вы сможете расширить его дополнительными метриками, а также адаптировать под нужный дизайн.
Сначала определим контейнер виджета и несколько элементов для вывода команд, счета и пары ключевых показателей.
<div id="match-widget">
<div class="mw-header">
<span id="mw-home-team"></span>
<span id="mw-score"></span>
<span id="mw-away-team"></span>
</div>
<div class="mw-meta">
<span id="mw-status"></span>
<span id="mw-minute"></span>
</div>
<div class="mw-stats">
<div class="mw-stat-row">
<span>Владение мячом</span>
<span id="mw-possession-home"></span>
<span id="mw-possession-away"></span>
</div>
<div class="mw-stat-row">
<span>Удары по воротам</span>
<span id="mw-shots-home"></span>
<span id="mw-shots-away"></span>
</div>
</div>
</div>
#match-widget {
max-width: 420px;
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 12px;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
.mw-header {
display: flex;
justify-content: space-between;
font-weight: 600;
margin-bottom: 8px;
}
.mw-meta {
display: flex;
justify-content: space-between;
font-size: 12px;
color: #777;
margin-bottom: 8px;
}
.mw-stats {
border-top: 1px solid #f0f0f0;
padding-top: 8px;
}
.mw-stat-row {
display: flex;
justify-content: space-between;
font-size: 13px;
margin: 4px 0;
}
.mw-stat-row span:first-child {
flex: 1 1 auto;
}
.mw-stat-row span:nth-child(2),
.mw-stat-row span:nth-child(3) {
width: 40px;
text-align: center;
}
const API_KEY = 'YOUR_API_KEY';
const MATCH_ID = 14570728;
async function fetchMatch() {
const res = await fetch(
`https://api.api-sport.ru/v2/football/matches/${MATCH_ID}`,
{ headers: { 'Authorization': API_KEY } }
);
if (!res.ok) throw new Error('Ошибка API: ' + res.status);
return res.json();
}
function extractStat(match, key) {
const allPeriod = match.matchStatistics?.find(s => s.period === 'ALL');
if (!allPeriod) return null;
for (const group of allPeriod.groups) {
const item = group.statisticsItems.find(i => i.key === key);
if (item) return item;
}
return null;
}
async function renderMatchWidget() {
const match = await fetchMatch();
document.getElementById('mw-home-team').textContent = match.homeTeam.name;
document.getElementById('mw-away-team').textContent = match.awayTeam.name;
document.getElementById('mw-score').textContent =
`${match.homeScore.current} : ${match.awayScore.current}`;
document.getElementById('mw-status').textContent = match.status;
document.getElementById('mw-minute').textContent =
match.currentMatchMinute ? match.currentMatchMinute + "'" : '';
const possession = extractStat(match, 'ballPossession');
const shots = extractStat(match, 'totalShotsOnGoal');
if (possession) {
document.getElementById('mw-possession-home').textContent = possession.home;
document.getElementById('mw-possession-away').textContent = possession.away;
}
if (shots) {
document.getElementById('mw-shots-home').textContent = shots.home;
document.getElementById('mw-shots-away').textContent = shots.away;
}
}
renderMatchWidget().catch(console.error);
Этот пример демонстрирует базовый подход к интеграции. В продакшене вы добавите обработку состояний загрузки (skeleton-экраны), локализацию статусов, а также поддержку разных видов спорта, используя sportSlug и единый интерфейс виджета, построенный поверх универсальных полей API Sport Events.
Как сделать обновление статистики матча в реальном времени через API
Для живого спорта важно, чтобы пользователь видел изменения почти мгновенно. Самый простой способ реализовать это на JavaScript — периодический опрос API (polling). Вы запускаете интервал (например, раз в 15–30 секунд), который повторно вызывает эндпоинт /v2/football/matches/{matchId}, сравнивает новые данные с уже отрисованными и обновляет только изменившиеся элементы интерфейса: счет, текущую минуту, ключевые метрики из matchStatistics и список liveEvents.
При использовании платформы api-sport.ru такой подход уже дает плавное обновление статистики. В ближайшее время сервис дополнит REST-интерфейс WebSocket-каналами, что позволит отказаться от частых опросов и получать события по подписке в режиме push. Ваш виджет сможет слушать конкретный матч или турнир и моментально реагировать на голы, карточки, замены и изменения коэффициентов, не создавая лишнюю нагрузку на API и фронтенд.
const API_KEY = 'YOUR_API_KEY';
const MATCH_ID = 14570728;
let lastHomeScore = null;
let lastAwayScore = null;
async function updateMatchLoop() {
try {
const res = await fetch(
`https://api.api-sport.ru/v2/football/matches/${MATCH_ID}`,
{ headers: { 'Authorization': API_KEY } }
);
if (!res.ok) throw new Error('Ошибка API: ' + res.status);
const match = await res.json();
if (match.homeScore.current !== lastHomeScore ||
match.awayScore.current !== lastAwayScore) {
lastHomeScore = match.homeScore.current;
lastAwayScore = match.awayScore.current;
// Обновляем счет и анимацию в виджете
document.getElementById('mw-score').textContent =
`${lastHomeScore} : ${lastAwayScore}`;
}
if (match.currentMatchMinute) {
document.getElementById('mw-minute').textContent =
match.currentMatchMinute + "'";
}
// Аналогично можно обновлять matchStatistics и liveEvents
} catch (e) {
console.error(e);
}
}
// Запускаем обновление каждые 20 секунд (значение подберите под свои лимиты)
setInterval(updateMatchLoop, 20000);
updateMatchLoop();
Важно выдерживать баланс между актуальностью и нагрузкой. Учитывайте тарифные лимиты и кэширование на стороне API, не ставьте интервал в 1–2 секунды без крайней необходимости. С появлением WebSocket от api-sport.ru вы сможете перевести виджет на архитектуру с подпиской на события, оставив REST для первоначальной загрузки данных и резервных сценариев.
Интеграция виджета статистики матча на сайт и типичные ошибки при работе с API
Готовый виджет на JavaScript можно встроить практически в любой сайт: статический лендинг, CMS вроде WordPress, новостной портал или букмекерскую витрину. Базовый вариант интеграции — разместить HTML-контейнер виджета в нужном месте шаблона и подключить JS-файл с логикой загрузки и отрисовки статистики. Если у вас несколько страниц с матчами, можно передавать matchId в data-атрибуте контейнера или через параметры URL, чтобы один и тот же скрипт обслуживал множество виджетов.
Частая ошибка — использование API-ключа напрямую в клиентском коде без какого-либо прокси. Для публичных и высоконагруженных проектов лучше вынести все запросы к Sport Events API на backend (Node.js, PHP, Python) и уже с сервера отдавать фронтенду только подготовленные данные. Это защищает ключ от утечки и позволяет централизованно управлять кэшированием, лимитами и логированием. Еще одна типичная проблема — игнорирование статуса матча и часовых поясов: виджет продолжает обновляться после финального свистка или показывает некорректное время начала матча для пользователей из других регионов.
Также разработчики иногда не учитывают особенности структуры matchStatistics и жестко привязываются к текстовым названиям групп и метрик. Рекомендуется опираться на стабильные ключи (key у statisticsItems) и строить интерфейс так, чтобы при появлении новых показателей в API их было легко добавить без переработки логики. Завершая интеграцию, протестируйте поведение виджета на разных состояниях матча (не начался, в перерыве, завершен, перенесен), на мобильных устройствах и при временной недоступности API. Используя данные Sport Events от api-sport.ru и аккуратную архитектуру, вы получите стабильный, быстрый и расширяемый виджет статистики, который можно масштабировать на новые виды спорта и турниры.




