fix: авто-перезапуск браузера при закрытом контексте (BrowserContext.new_page: has been closed)
This commit is contained in:
1 parent
4dcaffd4c4
commit
e4cd06a23d
1 file changed
+51
-11
+51
-11
@@ -42,6 +42,7 @@ SUBMIT_BUTTONS = [
|
||||
# Доступны ТОЛЬКО из браузерного потока.
|
||||
_browsers = {}
|
||||
_pages = {}
|
||||
_playwrights = {}
|
||||
|
||||
# ---------- Браузерный поток ----------
|
||||
|
||||
@@ -111,9 +112,8 @@ def get_proxy_config():
|
||||
|
||||
# ---------- Внутренние функции (только из браузерного потока) ----------
|
||||
|
||||
def _launch_context(account_dir):
|
||||
def _launch_context_with(p, account_dir):
|
||||
"""Запускает браузер с профилем аккаунта и подставляет cookies сессии."""
|
||||
p = sync_playwright().start()
|
||||
kwargs = dict(
|
||||
user_data_dir=os.path.join(account_dir, "profile"),
|
||||
headless=is_headless(),
|
||||
@@ -127,6 +127,15 @@ def _launch_context(account_dir):
|
||||
return context
|
||||
|
||||
|
||||
def _context_alive(ctx):
|
||||
"""Проверяет, жив ли контекст (лёгкая операция, не создаёт страниц)."""
|
||||
try:
|
||||
ctx.pages
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def _inject_session_cookies(context, account_dir):
|
||||
"""Подставляет cookies из session.txt — вход на hh.ru без ручного логина."""
|
||||
path = os.path.join(account_dir, "session.txt")
|
||||
@@ -149,10 +158,33 @@ def _inject_session_cookies(context, account_dir):
|
||||
|
||||
|
||||
def _get_context(account_dir, user, account):
|
||||
"""Возвращает живой контекст; если браузер умер — перезапускает."""
|
||||
key = (user, account)
|
||||
if key not in _browsers:
|
||||
_browsers[key] = _launch_context(account_dir)
|
||||
return _browsers[key]
|
||||
ctx = _browsers.get(key)
|
||||
if ctx is None or not _context_alive(ctx):
|
||||
if ctx is not None:
|
||||
print(f" ⚠ Браузер {key} закрыт — перезапускаю")
|
||||
_close_context(key)
|
||||
p = sync_playwright().start()
|
||||
try:
|
||||
ctx = _launch_context_with(p, account_dir)
|
||||
except Exception:
|
||||
p.stop()
|
||||
raise
|
||||
_browsers[key] = ctx
|
||||
_playwrights[key] = p
|
||||
return ctx
|
||||
|
||||
|
||||
def _new_page(account_dir, user, account):
|
||||
"""Создаёт страницу; если контекст умер между проверкой и созданием —
|
||||
перезапускает браузер и пробует ещё раз."""
|
||||
try:
|
||||
return _get_context(account_dir, user, account).new_page()
|
||||
except Exception:
|
||||
print(f" ⚠ Не удалось создать страницу для {(user, account)} — перезапускаю браузер")
|
||||
_close_context((user, account))
|
||||
return _get_context(account_dir, user, account).new_page()
|
||||
|
||||
|
||||
def _save_screenshot(page, screenshot_dir, vid):
|
||||
@@ -181,8 +213,7 @@ def open_response_page(account_dir, user, account, vacancy, message,
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
context = _get_context(account_dir, user, account)
|
||||
page = context.new_page()
|
||||
page = _new_page(account_dir, user, account)
|
||||
_pages[key] = page
|
||||
page.goto(vacancy["url"], timeout=45000)
|
||||
page.wait_for_timeout(2500)
|
||||
@@ -276,15 +307,14 @@ def confirm_send(user, account, vid):
|
||||
def open_login_page(account_dir, user, account):
|
||||
"""Открывает hh.ru в браузере (для ручного входа, локальный режим с экраном)."""
|
||||
key = (user, account)
|
||||
context = _get_context(account_dir, user, account)
|
||||
page = context.new_page()
|
||||
page = _new_page(account_dir, user, account)
|
||||
_pages[key] = page
|
||||
page.goto("https://hh.ru", timeout=45000)
|
||||
return True, "Страница hh.ru открыта"
|
||||
|
||||
|
||||
def close_context(user, account):
|
||||
key = (user, account)
|
||||
def _close_context(key):
|
||||
"""Закрывает контекст и останавливает playwright-инстанс (из браузерного потока)."""
|
||||
if key in _browsers:
|
||||
try:
|
||||
_browsers[key].close()
|
||||
@@ -292,6 +322,16 @@ def close_context(user, account):
|
||||
pass
|
||||
_browsers.pop(key, None)
|
||||
_pages.pop(key, None)
|
||||
p = _playwrights.pop(key, None)
|
||||
if p:
|
||||
try:
|
||||
p.stop()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def close_context(user, account):
|
||||
_close_context((user, account))
|
||||
|
||||
|
||||
# ---------- Публичные обёртки (можно вызывать из любого потока) ----------
|
||||
|
||||
Reference in new issue
Block a user