在给定 context 中执行打码逻辑
(self, context, project_id: str, website_key: str, action: str)
| 1820 | await self.recycle_browser(reason="force_close_all", rotate_profile=False) |
| 1821 | |
| 1822 | async def _execute_captcha(self, context, project_id: str, website_key: str, action: str) -> Optional[str]: |
| 1823 | """在给定 context 中执行打码逻辑""" |
| 1824 | page = None |
| 1825 | try: |
| 1826 | page = await context.new_page() |
| 1827 | await self._apply_browser_environment_patch(page, label="captcha_page") |
| 1828 | await page.add_init_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined});") |
| 1829 | ready = await self._prepare_flow_runtime_page( |
| 1830 | page, |
| 1831 | project_id, |
| 1832 | website_key, |
| 1833 | action, |
| 1834 | context_label="打码", |
| 1835 | ) |
| 1836 | if not ready: |
| 1837 | return None |
| 1838 | |
| 1839 | token = await asyncio.wait_for( |
| 1840 | page.evaluate(f""" |
| 1841 | (actionName) => {{ |
| 1842 | return new Promise((resolve, reject) => {{ |
| 1843 | const timeout = setTimeout(() => reject(new Error('timeout')), 25000); |
| 1844 | grecaptcha.enterprise.execute('{website_key}', {{action: actionName}}) |
| 1845 | .then(t => {{ clearTimeout(timeout); resolve(t); }}) |
| 1846 | .catch(e => {{ clearTimeout(timeout); reject(e); }}); |
| 1847 | }}); |
| 1848 | }} |
| 1849 | """, action), |
| 1850 | timeout=30 |
| 1851 | ) |
| 1852 | |
| 1853 | # 额外等待几秒,确保 enterprise 请求链路完全稳定 |
| 1854 | post_wait_seconds = float(getattr(config, "browser_recaptcha_settle_seconds", 3) or 3) |
| 1855 | if post_wait_seconds > 0: |
| 1856 | debug_logger.log_info( |
| 1857 | f"[BrowserCaptcha] Token-{self.token_id} token已获取,额外等待 {post_wait_seconds:.1f}s 后返回" |
| 1858 | ) |
| 1859 | await asyncio.sleep(post_wait_seconds) |
| 1860 | |
| 1861 | return token |
| 1862 | except Exception as e: |
| 1863 | msg = f"{type(e).__name__}: {str(e)}" |
| 1864 | debug_logger.log_warning(f"[BrowserCaptcha] Token-{self.token_id} 打码失败: {msg[:200]}") |
| 1865 | return None |
| 1866 | finally: |
| 1867 | if page: |
| 1868 | try: |
| 1869 | await page.close() |
| 1870 | except: |
| 1871 | pass |
| 1872 | |
| 1873 | async def _execute_custom_captcha( |
| 1874 | self, |
no test coverage detected