0.0.3
This commit is contained in:
143
back/utils/browser_api.py
Normal file
143
back/utils/browser_api.py
Normal file
@@ -0,0 +1,143 @@
|
||||
import datetime
|
||||
import asyncio
|
||||
import httpx
|
||||
from loguru import logger
|
||||
from utils.decorators import handle_exceptions_unified
|
||||
|
||||
|
||||
class BrowserApi:
|
||||
"""
|
||||
浏览器接口
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.local_url = 'http://127.0.0.1:54345'
|
||||
self.headers = {'Content-Type': 'application/json'}
|
||||
# 使用异步 HTTP 客户端,启用连接池和超时设置
|
||||
self.client = httpx.AsyncClient(
|
||||
base_url=self.local_url,
|
||||
headers=self.headers,
|
||||
timeout=httpx.Timeout(30.0, connect=10.0), # 总超时30秒,连接超时10秒
|
||||
limits=httpx.Limits(max_keepalive_connections=50, max_connections=100), # 连接池配置
|
||||
)
|
||||
|
||||
async def __aenter__(self):
|
||||
"""异步上下文管理器入口"""
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
||||
"""异步上下文管理器出口,关闭客户端"""
|
||||
await self.aclose()
|
||||
|
||||
async def aclose(self):
|
||||
"""关闭 HTTP 客户端"""
|
||||
if self.client:
|
||||
await self.client.aclose()
|
||||
|
||||
# 打开指纹浏览器
|
||||
@handle_exceptions_unified()
|
||||
async def open_browser(self, id: str, jc: int = 0):
|
||||
"""
|
||||
打开指纹浏览器(异步优化版本)
|
||||
:param jc: 计次
|
||||
:param id: 浏览器id
|
||||
:return:http, pid
|
||||
"""
|
||||
if jc > 3:
|
||||
return None, None
|
||||
url = '/browser/open'
|
||||
data = {
|
||||
'id': id
|
||||
}
|
||||
try:
|
||||
res = await self.client.post(url, json=data)
|
||||
res.raise_for_status() # 检查 HTTP 状态码
|
||||
res_data = res.json()
|
||||
logger.info(f'打开指纹浏览器: {res_data}')
|
||||
if not res_data.get('success'):
|
||||
logger.error(f'打开指纹浏览器失败: {res_data}')
|
||||
return await self.open_browser(id, jc + 1)
|
||||
data = res_data.get('data')
|
||||
http = data.get('http')
|
||||
pid = data.get('pid')
|
||||
logger.info(f'打开指纹浏览器成功: {http}, {pid}')
|
||||
return http, pid
|
||||
except httpx.TimeoutException as e:
|
||||
logger.error(f'打开指纹浏览器超时: {e}')
|
||||
if jc < 3:
|
||||
return await self.open_browser(id, jc + 1)
|
||||
return None, None
|
||||
except httpx.RequestError as e:
|
||||
logger.error(f'打开指纹浏览器请求错误: {e}')
|
||||
if jc < 3:
|
||||
return await self.open_browser(id, jc + 1)
|
||||
return None, None
|
||||
except Exception as e:
|
||||
logger.error(f'打开指纹浏览器异常: {e}')
|
||||
if jc < 3:
|
||||
return await self.open_browser(id, jc + 1)
|
||||
return None, None
|
||||
|
||||
# 关闭指纹浏览器
|
||||
@handle_exceptions_unified()
|
||||
async def close_browser(self, id: str, jc: int = 0):
|
||||
"""
|
||||
关闭指纹浏览器(异步优化版本)
|
||||
:param jc: 计次
|
||||
:param id: 浏览器id
|
||||
:return:
|
||||
"""
|
||||
if jc > 3:
|
||||
return None
|
||||
url = '/browser/close'
|
||||
data = {
|
||||
'id': id
|
||||
}
|
||||
try:
|
||||
res = await self.client.post(url, json=data)
|
||||
res.raise_for_status() # 检查 HTTP 状态码
|
||||
res_data = res.json()
|
||||
logger.info(f'关闭指纹浏览器: {res_data}')
|
||||
if not res_data.get('success'):
|
||||
msg = res_data.get('msg', '')
|
||||
# 如果浏览器正在打开中,等待后重试(不是真正的错误)
|
||||
if '正在打开中' in msg or 'opening' in msg.lower():
|
||||
if jc < 3:
|
||||
# 等待 1-3 秒后重试(根据重试次数递增等待时间)
|
||||
wait_time = (jc + 1) * 1.0 # 第1次重试等1秒,第2次等2秒,第3次等3秒
|
||||
logger.info(f'浏览器正在打开中,等待 {wait_time} 秒后重试关闭: browser_id={id}')
|
||||
await asyncio.sleep(wait_time)
|
||||
return await self.close_browser(id, jc + 1)
|
||||
else:
|
||||
# 超过重试次数,记录警告但不作为错误
|
||||
logger.warning(f'关闭指纹浏览器失败(浏览器正在打开中,已重试3次): browser_id={id}')
|
||||
return None
|
||||
else:
|
||||
# 其他错误,记录为错误并重试
|
||||
logger.error(f'关闭指纹浏览器失败: {res_data}')
|
||||
if jc < 3:
|
||||
await asyncio.sleep(0.5) # 短暂等待后重试
|
||||
return await self.close_browser(id, jc + 1)
|
||||
return None
|
||||
logger.info(f'关闭指纹浏览器成功: browser_id={id}')
|
||||
return True
|
||||
except httpx.TimeoutException as e:
|
||||
logger.error(f'关闭指纹浏览器超时: {e}')
|
||||
if jc < 3:
|
||||
await asyncio.sleep(1.0)
|
||||
return await self.close_browser(id, jc + 1)
|
||||
return None
|
||||
except httpx.RequestError as e:
|
||||
logger.error(f'关闭指纹浏览器请求错误: {e}')
|
||||
if jc < 3:
|
||||
await asyncio.sleep(1.0)
|
||||
return await self.close_browser(id, jc + 1)
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f'关闭指纹浏览器异常: {e}')
|
||||
if jc < 3:
|
||||
await asyncio.sleep(1.0)
|
||||
return await self.close_browser(id, jc + 1)
|
||||
return None
|
||||
|
||||
browser_api = BrowserApi()
|
||||
Reference in New Issue
Block a user