"""Пагинация phpBB. phpBB: пагинация через параметр start=N, где N = (page-1) * items_per_page. На странице раздела: 2 3 ... 72 На странице темы: 2 ... """ import re, logging from bs4 import BeautifulSoup log = logging.getLogger(__name__) def count(soup: BeautifulSoup) -> int: """Сколько страниц в пагинации. Если нет — 1.""" for cls in ("pagination", "page-nav"): nav = soup.find("ul", class_=cls) if nav: break else: return 1 nums = set() for a in nav.select("a"): href = a.get("href", "") text = a.text.strip() # start=N из href m = re.search(r"[?&]start=(\d+)", href) if m: per_page = int(m.group(1)) # Определяем items_per_page по первому start if hasattr(count, "_per_page"): pass nums.add(per_page) # Числовой текст ссылки try: nums.add(int(text)) except ValueError: pass if not nums: return 1 # Находим максимальный номер страницы из текста ссылок max_page_num = max((int(a.text.strip()) for a in nav.select("a") if a.text.strip().isdigit()), default=1) # Находим max start max_start = max(nums) # Определяем per_page из наименьшего start > 0 positive_starts = [s for s in nums if s > 0] if positive_starts: per_page = min(positive_starts) else: # Не можем определить — возвращаем по тексту ссылок return max_page_num # Вычисляем: страниц = (max_start / per_page) + 1 pages = (max_start // per_page) + 1 return pages def page_url(base_url: str, page: int, per_page: int) -> str: """Сформировать URL для страницы пагинации. Args: base_url: URL без start= (напр. viewforum.php?f=22) page: номер страницы (1-based) per_page: элементов на странице """ if page <= 1: return base_url start = (page - 1) * per_page sep = "&" if "?" in base_url else "?" return f"{base_url}{sep}start={start}"