"""Пагинация phpBB. phpBB использует параметр ?start=N для пагинации, где: N = (page - 1) * items_per_page Страницы раздела: viewforum.php?f=22&start=25 ← страница 2 viewforum.php?f=22&start=50 ← страница 3 ... Страницы темы: viewtopic.php?f=22&t=123&start=10 ← страница 2 viewtopic.php?f=22&t=123&start=20 ← страница 3 ... HTML-структура пагинации: """ import re import logging from bs4 import BeautifulSoup log = logging.getLogger(__name__) def count_pages(soup: BeautifulSoup, per_page: int) -> int: """Определить количество страниц в пагинации phpBB. Алгоритм: 1. Ищем ul.pagination (или ul.page-nav). 2. Собираем все start=N из href. 3. Находим max_start. 4. Вычисляем: pages = max_start / per_page + 1. Args: soup: BeautifulSoup страницы раздела или темы. per_page: Количество элементов на странице (темы=25, посты=10). Returns: int: количество страниц (минимум 1). """ # Ищем контейнер пагинации (два варианта класса) nav = soup.find("ul", class_="pagination") if nav is None: nav = soup.find("ul", class_="page-nav") if nav is None: return 1 # Собираем все start=N из ссылок starts = set() for link in nav.select("a"): href = link.get("href", "") match = re.search(r"[?&]start=(\d+)", href) if match: starts.add(int(match.group(1))) if not starts: return 1 max_start = max(starts) pages = (max_start // per_page) + 1 return pages def page_url(base_url: str, page_num: int, per_page: int) -> str: """Сформировать URL страницы раздела phpBB. Формат: page=1 → base_url (без ?start=) page>1 → base_url + &start=N Args: base_url: URL страницы без параметра start (напр. viewforum.php?f=22). page_num: Номер страницы (1-based). per_page: Количество элементов на страницу. Returns: str: URL страницы с ?start= (если page>1). """ if page_num <= 1: return base_url start = (page_num - 1) * per_page separator = "&" if "?" in base_url else "?" return f"{base_url}{separator}start={start}" def topic_page_url(topic_url: str, page_num: int, per_page: int) -> str: """Сформировать URL страницы темы phpBB. Args: topic_url: Полный URL темы. page_num: Номер страницы (1-based, начиная с 2). per_page: Количество постов на страницу. Returns: str: URL страницы темы с ?start=. """ if page_num <= 1: return topic_url start = (page_num - 1) * per_page separator = "&" if "?" in topic_url else "?" return f"{topic_url}{separator}start={start}"