fix: audit findings — edge cases in paginate, output, run

- paginate.py: max(nums) on empty set → guard
- paginate.py: HEAD fallback to GET if server doesn't support HEAD
- output.py: disk health check every 500 topics
- run.py: avoid page-1 extra redirect
- __main__.py: URL validation (must contain vwts.ru)
This commit is contained in:
2026-06-04 08:58:09 +03:00
parent 010b10c43e
commit 1cfa6d1595
4 changed files with 32 additions and 13 deletions
+20 -10
View File
@@ -44,7 +44,20 @@ def count(soup: BeautifulSoup) -> int:
except ValueError:
pass # "…", "Назад", "Вперёд"
return max(nums) if nums else 1
return max(nums) if nums else 1 # защита от пустого pageNav
def _head_or_get(session, url: str, timeout=(10, 30)) -> int:
"""HEAD-запрос с fallback на GET (не все серверы поддерживают HEAD)."""
try:
r = session.head(url, timeout=timeout, allow_redirects=True)
if r.status_code in (405, 501): # HEAD не поддерживается
r = session.get(url, timeout=timeout,
allow_redirects=True, stream=True)
r.close()
return r.status_code
except Exception:
return 500
def verify_last(section_url: str, claimed: int, session) -> int:
@@ -57,19 +70,16 @@ def verify_last(section_url: str, claimed: int, session) -> int:
return claimed
try:
import requests
r = session.head(f"{section_url}page-{claimed}",
timeout=(10, 30), allow_redirects=True)
if r.status_code < 400:
status = _head_or_get(session, f"{section_url}page-{claimed}")
if status < 400:
return claimed
# Бинарный поиск
# Бинарный поиск последней существующей страницы
lo, hi = 1, claimed
while lo < hi:
mid = (lo + hi + 1) // 2
hr = session.head(f"{section_url}page-{mid}",
timeout=(10, 30), allow_redirects=True)
if hr.status_code >= 400:
hr = _head_or_get(session, f"{section_url}page-{mid}")
if hr >= 400:
hi = mid - 1
else:
lo = mid
@@ -78,4 +88,4 @@ def verify_last(section_url: str, claimed: int, session) -> int:
return lo
except Exception:
return claimed # не смогли — верим сайту
return claimed