Документация проекта: Парсинг и генерация ставок на тотализатор (Correct Score)
Общее описание
Программа предназначена для автоматического сбора данных с веб-сайта тотализатора (azbet.com), парсинга коэффициентов и вероятностей на матчи с корректным счётом (Correct Score), и последующей генерации пакетов ставок (купонов) с соблюдением заданных ограничений.
Основные этапы работы:
Получение списка доступных тиражей (с идентификатором и статусом «Приём»).
Загрузка страницы текущего розыгрыша (тиража) с коэффициентами для каждого матча.
Извлечение вероятностей (коэффициентов и пула) для всех возможных исходов.
Преобразование вероятностей в целочисленные веса (количество вариантов на исход) с учётом общего размера пакета (125 билетов).
Генерация уникальных комбинаций исходов (вариантов) с проверкой на допустимость (ограничения на распределение исходов и минимальное расстояние Хэмминга между вариантами).
Формирование текстового файла с купонами для загрузки в систему.
Проект предназначен для использования в среде Google Colab (монтирование Google Drive). Все промежуточные данные сохраняются в папку runs/{run_number}/, где run_number – идентификатор тиража.
Основные модули и зависимости
Импортируемые библиотеки:
bs4, BeautifulSoup – парсинг HTML.
requests – HTTP-запросы.
pandas, numpy – работа с табличными данными.
pandarallel – параллельная обработка (не используется активно, но инициализируется).
tqdm – прогресс-бары.
fake-useragent – генерация случайного User-Agent.
dataclasses – для создания классов-структур.
re, os, math, random, itertools, collections – вспомогательные модули.
Константы и глобальные переменные
Имя Значение Назначение
FILE_PATH '/content/gdrive/MyDrive/files/' Базовая папка на Google Drive для хранения данных.
HEADERS {'User-Agent': UserAgent().chrome} Заголовки HTTP-запроса.
RUN_DATA_HTML 'toto_cs_home.html' Имя файла для сохранения главной страницы со списком тиражей.
PARSE_HTML 'toto_current_game.html' Имя файла для сохранения страницы текущего розыгрыша.
BK_LIST_CS Список из 17 строк (например, 'BK_1:0', …) Названия столбцов для коэффициентов букмекера (Correct Score).
POOL_LIST_CS Список из 17 строк (например, 'Pool_1:0', …) Названия столбцов для пула (распределение ставок).
COUPON_PRICE 0.2 Стоимость одного билета (купона) в евро.
PACKET_SIZE 125 Количество билетов в одном пакете.
MB_CS_HOME 'http://azbet.com/sttot/pbstyle/sttot16.aspx?GMT=+3' URL главной страницы тотализатора.
CS_WAYS ['A','B','C','G','H','I','K','L','M','Q'] Буквенные обозначения исходов для каждого матча (порядок соответствует индексам).
CS_UNDER ['A','B','G','H','K','L'] Набор исходов, считающихся «низовыми» (используется при фильтрации вариантов).
CS_SCORES ['1:0','2:0','2:1','0:0','1:1','2:2','0:1','0:2','1:2','ЛД'] Фактические счета, соответствующие буквенным обозначениям.
Вспомогательные функции
get_content(url: str, headers: dict) -> str
Выполняет HTTP GET-запрос, возвращает текст ответа (HTML). При ошибке выбрасывает исключение через raise_for_status().
write_data(file_path: str, data: str) -> None
Записывает строку data в файл по пути file_path (кодировка UTF-8).
write_csv(file_path: str, data: pd.DataFrame, run: int, html: str) -> None
Создаёт подпапку runs/{run}/, сохраняет DataFrame в CSV (разделитель ;, без индекса) и перемещает файл html из корня в подпапку. Использует os.replace.
check_variant(variant: str) -> bool
Проверяет, удовлетворяет ли строка-вариант следующим условиям:
максимальная частота любого символа < 4;
количество уникальных символов > 4;
количество символов из CS_UNDER > 2 и < 6.
Возвращает True, если все условия выполнены.
probes_normalizer(bk_probes: list) -> list
Принимает список списков коэффициентов (для каждого матча). Исключает индексы [3,4,5,9,13,14,15] (соответствуют нулевым или нестандартным исходам), пересчитывает проценты так, чтобы сумма стала 100%, округляет до двух знаков. Возвращает нормализованные вероятности.
ham_distance(incoming_string_1: str, incoming_string_2: str) -> int
Вычисляет расстояние Хэмминга (количество несовпадающих символов) между двумя строками одинаковой длины.
check_candidate(current_candidate: str, checked_candidates: List[str]) -> bool
Проверяет, что расстояние Хэмминга от current_candidate до любого из уже добавленных кандидатов больше 2. Используется для обеспечения минимального разнообразия в пакете.
decrement_weights(ways_counts: List[List[int]], step_indices: List[int]) -> None
Уменьшает на 1 значения в каждой строке ways_counts по индексам, переданным в step_indices. Используется для обновления весов после добавления варианта.
extract_content_data(data) -> pd.DataFrame
Принимает список тегов
(матчи) со страницы розыгрыша. Для каждого матча извлекает:
номер матча (Number);
названия команд (Teams);
коэффициенты и пул для каждого счёта (через атрибут title). Возвращает DataFrame с колонками, соответствующими BK_LIST_CS и POOL_LIST_CS. Преобразует числовые колонки в float.
Классы
RunDataParserCS
Назначение: Получение информации о текущем тираже (ссылка на детальную страницу и номер тиража) со статусом «Приём».
Атрибуты:
url – URL главной страницы списка тиражей.
file_path – базовая папка для сохранения.
html – имя файла для сохранения главной страницы.
_html_path, _src – внутренние.
run_url – URL детальной страницы текущего принимаемого тиража.
run_number – номер тиража (целое число).
Методы:
__post_init__() – вызывает _parse_probes() (загружает страницу, если нет файла) и _extract_data().
_parse_probes() – загружает HTML с url (если файл отсутствует) и сохраняет его в _src.
_extract_data() – парсит _src, извлекает все строки таблицы (tr.sttot-row), для каждой получает href, статус и номер тиража из текста ссылки. Возвращает кортеж (href, run_number) для первой записи со статусом 'Прием'. После извлечения удаляет файл _html_path (os.remove).
Использование: создаётся в main() для получения run_url и run_number.
ProbesParserCS
Назначение: Загрузка и парсинг страницы конкретного розыгрыша (по ссылке из run_url), извлечение данных по матчам и сохранение их в CSV.
Атрибуты:
url – относительный URL детальной страницы (например, tot_detail16.aspx?id=...).
file_path – базовая папка.
html – имя файла для сохранения (обычно PARSE_HTML).
run_number – номер тиража (целое).
_full_url – полный URL (склеивается с базовым http://azbet.com/sttot/pbstyle/).
_html_path – полный путь к файлу сохранения.
Методы:
__post_init__() – формирует _full_url и _html_path, вызывает _parse_probes().
_parse_probes() – проверяет наличие файла в runs/{run_number}/, если нет – загружает с _full_url и сохраняет. Затем парсит HTML, находит все
, передаёт в extract_content_data(), после чего вызывает write_csv() для сохранения DataFrame в CSV и перемещения HTML-файла в папку тиража.
ProbesArrayCS
Назначение: Загрузка сохранённого CSV-файла с данными по матчам и формирование списков вероятностей для букмекерских коэффициентов и пула.
Атрибуты:
file_path – базовая папка.
run – номер тиража.
columns_bk – список названий колонок для BK (букмекер).
columns_pool – список названий колонок для Pool (пул).
run_probes_bk_prep – список списков вероятностей из BK-колонок.
run_probes_pool – список списков вероятностей из Pool-колонок.
run_probes_bk – итоговый список, где для каждого матча выбираются значения из run_probes_pool, если сумма BK-вероятностей равна 0 (иначе – из run_probes_bk_prep).
Методы:
__post_init__() – вызывает _get_probes_array для BK и Pool, затем формирует run_probes_bk по указанному правилу.
_get_probes_array(incoming_probes: list) -> list – читает CSV, извлекает указанные колонки, преобразует в список списков и возвращает.
WaysCount
Назначение: Преобразование вероятностей (в процентах) в целочисленные веса (количество билетов на каждый исход) для заданного размера пакета (total_ways).
Атрибуты:
probes_bk_list – список списков вероятностей (сумма по строке должна быть 100).
total_ways – общее количество билетов в пакете (например, 125).
result_ways_list – результат работы: список списков целых чисел (веса) для каждого матча.
Методы:
__post_init__() – запускает _run() и сохраняет результат в result_ways_list.
_run() – для каждого матча:
Берёт целую часть от (total_ways * prob / 100).
Вычисляет дробные части и сортирует индексы по убыванию дробной части.
Суммирует целые части, вычисляет дефицит до total_ways.
Распределяет недостающие единицы по индексам с наибольшей дробной частью (по одному за шаг).
Возвращает итоговый список весов.
PacketCreator
Назначение: Генерация пакета уникальных вариантов (строк из букв CS_WAYS) на основе весов, с учётом ограничений на разнообразие и минимальное расстояние Хэмминга.
Атрибуты:
ways_count – исходные веса (список списков).
packet_size – количество вариантов для генерации.
incomming_variants – список уже существующих вариантов (по умолчанию пустой, может быть передан).
_most_common_indexes – индексы исходов, которые считаются наиболее вероятными (по умолчанию [0,2,4,6,8,9]). Используется для увеличения весов при генерации.
_ways_count_dec – модифицированный список весов (значения увеличиваются на 2 для указанных индексов, на 1 для остальных) – это влияет на вероятности выбора при генерации.
packet_list – итоговый список сгенерированных вариантов (включая incomming_variants).
Методы:
__post_init__() – создаёт _ways_count_dec и запускает _run_until_zero().
_generate_candidate() – для каждого матча выбирает исход с вероятностью, пропорциональной весу (в _ways_count_dec). Использует random.choices().
_run_until_zero() – основной цикл:
Начинает с history = incomming_variants.copy().
Пока len(history) < len(incomming_variants) + packet_size:
Генерирует индексы через _generate_candidate().
Преобразует их в строку step_variant (по CS_WAYS).
Проверяет check_variant() и check_candidate() (расстояние > 2).
Если проходит – добавляет в history, уменьшает веса через decrement_weights().
Иначе продолжает.
Возвращает history.
CouponCSForBetting
Назначение: Формирование текстового файла с купонами для загрузки в систему ставок.
Атрибуты:
incoming_list – список вариантов (строк) или один вариант.
price – стоимость одного билета (число).
file_path – базовая папка.
run_number – номер тиража (опционально).
number_of_tickets – количество билетов = len(incoming_list).
file_name – полное имя файла (например, run125_125tickets.txt).
prepared_variants_list – список строк в формате купона.
Методы:
__post_init__() – вычисляет number_of_tickets, вызывает _create_filename() и _create_coupons() для создания списка, затем _strip_quotes() (реально вызывает _write_file()).
_create_filename() – генерирует путь: {file_path}runs/{run_number}/run{run_number}_{number_of_tickets}tickets.txt.
_create_coupons() – для каждого варианта создаёт строку формата: {price}|1-({score1});2-({score2});...;8-({score8})#. Для каждого символа варианта находит соответствующий счёт из CS_SCORES по индексу в CS_WAYS.
_write_file() – записывает все строки в файл (по одной на строку).
_strip_quotes() – фактически дублирует _write_file() (в текущей реализации просто вызывает _write_file() после проверки на run_number).
Функция main()
Основной сценарий выполнения:
Создаёт экземпляр RunDataParserCS (фактически трижды – это неэффективно, но в коде так). Из него извлекает run_url и run_number.
Создаёт ProbesParserCS с полученными run_url, FILE_PATH, PARSE_HTML и run_number. Это загружает страницу розыгрыша, парсит и сохраняет CSV.
Создаёт ProbesArrayCS для чтения сохранённого CSV, получает run_probes_bk (список вероятностей).
Нормализует вероятности через probes_normalizer().
Создаёт WaysCount для расчёта весов (размер пакета = PACKET_SIZE).
Создаёт PacketCreator с весами и размером пакета, получает список вариантов.
Создаёт CouponCSForBetting для генерации файла купонов.
После выполнения в папке runs/{run_number}/ появляются:
run_{run_number}.csv – данные по матчам;
toto_current_game.html – исходная HTML-страница розыгрыша;
run{run_number}_{packet_size}tickets.txt – файл с купонами.
Запуск
Скрипт предназначен для запуска в среде Google Colab. Предварительно необходимо:
Смонтировать Google Drive.
Установить недостающие пакеты (указаны в первой ячейке: fake-useragent, pandarallel).
Убедиться, что папка FILE_PATH существует.
После запуска main() вся логика выполняется автоматически.
Зависимости
Python 3.7+
beautifulsoup4
lxml (или html.parser)
requests
pandas, numpy
pandarallel
tqdm
fake-useragent
dataclasses (встроено в Python 3.7+)
Примечания
Проверка статуса «Прием» выполняется только по первому совпадению в списке тиражей – предполагается, что такой тираж один на момент запуска.
Все промежуточные файлы сохраняются в Google Drive; при повторном запуске с тем же номером тиража данные будут перезаписаны (CSV заменяется).