lada_scraper: парсер phpBB форума нива-лада.рф + доку

This commit is contained in:
2026-06-04 11:47:02 +03:00
parent 928c979509
commit eca5e3cda6
15 changed files with 1108 additions and 7 deletions
+86
View File
@@ -0,0 +1,86 @@
"""Пагинация phpBB.
phpBB: пагинация через параметр start=N, где N = (page-1) * items_per_page.
На странице раздела:
<a href="./viewforum.php?f=22&start=25">2</a>
<a href="./viewforum.php?f=22&start=50">3</a>
...
<a href="./viewforum.php?f=22&start=1800">72</a>
На странице темы:
<a href="./viewtopic.php?f=22&t=123&start=10">2</a>
...
"""
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}"