feat: многопоточный парсинг + forum survey

- Throttle: Thread-safe координация задержек
- BanDetector: автоопределение бана
- fetch: thread-local сессии вместо глобальной
- run: ThreadPoolExecutor + диапазоны страниц + мерж
- output/state: поддержка worker-папок и merge_states()
- __main__: --workers, --no-delay, --no-ban-test
- VWTS/forums-survey.md: обзор 20+ автофорумов
This commit is contained in:
2026-06-04 10:48:57 +03:00
parent 22ca83adf8
commit c3211f0602
8 changed files with 361 additions and 93 deletions
+24 -5
View File
@@ -7,13 +7,32 @@ from .config import DELAY, TIMEOUT, HEADERS
log = logging.getLogger(__name__)
session = requests.Session()
session.headers.update(HEADERS)
# Глобальный throttle — устанавливается из run()
throttle = None
def get(url: str) -> BeautifulSoup | None:
"""GET + ретраи (до 3). 404 — без ретрая, сразу None."""
time.sleep(DELAY)
def make_session() -> requests.Session:
"""Создать новую сессию (thread-safe)."""
s = requests.Session()
s.headers.update(HEADERS)
return s
def get(url: str, session: requests.Session = None) -> BeautifulSoup | None:
"""GET + ретраи (до 3). 404 — без ретрая, сразу None.
Args:
url: URL для загрузки
session: опциональная сессия (если None — создаётся временная)
"""
if session is None:
session = make_session()
if throttle:
throttle.wait()
else:
time.sleep(DELAY)
for n in range(3):
try:
r = session.get(url, timeout=TIMEOUT)