MCPcopy Create free account
hub / github.com/TheSmallHanCat/flow2api / BrowserCaptchaService

Class BrowserCaptchaService

src/services/browser_captcha.py:2540–3079  ·  view source on GitHub ↗

多浏览器轮询打码服务(单例模式) 支持配置浏览器数量,每个浏览器只开 1 个标签页,请求轮询分配

Source from the content-addressed store, hash-verified

2538
2539
2540class BrowserCaptchaService:
2541 """多浏览器轮询打码服务(单例模式)
2542
2543 支持配置浏览器数量,每个浏览器只开 1 个标签页,请求轮询分配
2544 """
2545
2546 _instance: Optional['BrowserCaptchaService'] = None
2547 _lock = asyncio.Lock()
2548
2549 def __init__(self, db=None):
2550 self.db = db
2551 self.website_key = "6LdsFiUsAAAAAIjVDZcuLhaHiDn5nnHVXVRQGeMV"
2552 self.base_user_data_dir = os.path.join(os.getcwd(), "browser_data_rt")
2553 self._browsers: Dict[int, TokenBrowser] = {}
2554 self._browsers_lock = asyncio.Lock()
2555 self._slot_allocation_lock = asyncio.Lock()
2556 self._slot_reservations: Dict[int, int] = {}
2557
2558 # ???????
2559 self._browser_count = 1 # ?? 1 ?????????
2560 self._round_robin_index = 0 # ????
2561 # ????
2562 self._stats = {
2563 "req_total": 0,
2564 "gen_ok": 0,
2565 "gen_fail": 0,
2566 "api_403": 0
2567 }
2568
2569 # ?????? _load_browser_count ???????
2570 self._token_semaphore = None
2571 self._idle_reaper_task: Optional[asyncio.Task] = None
2572
2573 async def _ensure_idle_reaper(self):
2574 if self._idle_reaper_task is None or self._idle_reaper_task.done():
2575 self._idle_reaper_task = asyncio.create_task(self._idle_reaper_loop())
2576
2577 async def _idle_reaper_loop(self):
2578 while True:
2579 try:
2580 await asyncio.sleep(15)
2581 idle_ttl = int(getattr(config, "browser_idle_ttl_seconds", 600) or 600)
2582 browsers = []
2583 async with self._browsers_lock:
2584 browsers = list(self._browsers.values())
2585 for browser in browsers:
2586 try:
2587 if browser.is_busy():
2588 continue
2589 if not browser.has_shared_browser():
2590 continue
2591 if browser.idle_seconds() < idle_ttl:
2592 continue
2593 await browser.recycle_browser(reason=f"idle_ttl_{idle_ttl}s", rotate_profile=False)
2594 except Exception as e:
2595 debug_logger.log_warning(f"[BrowserCaptcha] idle reaper failed: {e}")
2596 except asyncio.CancelledError:
2597 return

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected