直接复用页面,避免CF验证
This commit is contained in:
@@ -302,18 +302,25 @@ class BrowserPool:
|
||||
async def create_persistent_context(self, storage_state: dict[str, Any] | None = None) -> Any:
|
||||
"""创建一个由调用方负责生命周期的长存上下文。
|
||||
|
||||
用于 cf_clearance 保活复用:通过挑战后保留该上下文,后续请求在其内
|
||||
开新页面访问目标页(同一上下文内 cf_clearance 有效)。调用方需在不再
|
||||
使用时调用 close_context 释放。
|
||||
用于 cf_clearance 保活复用:通过挑战后保留该上下文及其页面,后续请求
|
||||
复用同一页面(当前标签页)重新导航。调用方需在不再使用时调用
|
||||
close_context 释放。
|
||||
"""
|
||||
await self._ensure_browser_ready()
|
||||
return await self._build_context_obj(storage_state)
|
||||
|
||||
@asynccontextmanager
|
||||
async def page_in_context(self, context: Any) -> AsyncIterator[Any]:
|
||||
"""在既有(长存)上下文中开一个页面,复用并发信号量。
|
||||
async def create_persistent_page(self, context: Any) -> Any:
|
||||
"""在长存上下文中创建一个长存页面(设置反检测请求头)。
|
||||
|
||||
结束时仅关闭页面,不关闭上下文(上下文生命周期由调用方维护)。
|
||||
该页面不会被自动关闭,调用方通过 close_context 关闭其所属上下文时一并释放。
|
||||
"""
|
||||
return await self._configure_page(context)
|
||||
|
||||
@asynccontextmanager
|
||||
async def navigation_slot(self) -> AsyncIterator[None]:
|
||||
"""获取一个并发槽位用于一次页面导航(不创建/关闭页面)。
|
||||
|
||||
用于在长存页面上做导航时复用全局并发信号量与回收计数。
|
||||
|
||||
Raises:
|
||||
ResourceBusyError: 等待可用槽位超时
|
||||
@@ -327,19 +334,12 @@ class BrowserPool:
|
||||
except TimeoutError as exc:
|
||||
raise ResourceBusyError() from exc
|
||||
|
||||
page = None
|
||||
counted = False
|
||||
try:
|
||||
self._active_contexts += 1
|
||||
counted = True
|
||||
page = await self._configure_page(context)
|
||||
yield page
|
||||
yield
|
||||
finally:
|
||||
if page is not None:
|
||||
try:
|
||||
await page.close()
|
||||
except Exception:
|
||||
logger.debug("关闭复用上下文页面失败", exc_info=True)
|
||||
if counted:
|
||||
self._active_contexts -= 1
|
||||
self._semaphore.release()
|
||||
|
||||
Reference in New Issue
Block a user