This commit is contained in:
2025-11-27 00:43:41 +08:00
parent d6944a3e3e
commit cec9198b8e
2 changed files with 164 additions and 204 deletions

View File

@@ -196,12 +196,13 @@ class BitBrowser:
url = f"{self.bit_host}:{bit_port}/browser/close"
headers = {'Content-Type': 'application/json'}
data = {'id': f'{pk}'}
requests.post(url, json=data, headers=headers).json()
time.sleep(5) # 等待5s等待浏览器关闭
# 关闭浏览器进程
# pid = self.bit_browser_pid(pk, bit_port)
# if pid is not None:
# os.system(f"kill -9 {pid}")
res = requests.post(url, json=data, headers=headers).json()
if not res.get('success'):
raise Exception(res)
bol = self.bit_browser_status(pk)
if bol:
raise Exception(f'浏览器ID {pk} 未正常关闭')
return True
# 删除比特币浏览器
@retry(max_retries=3, delay=1.0, backoff=1.0)
@@ -215,7 +216,10 @@ class BitBrowser:
url = f"{self.bit_host}:{bit_port}/browser/delete"
headers = {'Content-Type': 'application/json'}
data = {'id': f'{pk}'}
print(requests.post(url, json=data, headers=headers).json())
res = requests.post(url, json=data, headers=headers).json()
if not res.get('success'):
raise Exception(res)
return True
# 获取所有比特币浏览器
@retry(max_retries=3, delay=1.0, backoff=1.0)
@@ -275,210 +279,27 @@ class BitBrowser:
raise Exception(res)
return res['data'][pk]
@staticmethod
async def __request(method: str, url: str, params: dict = None, **kwargs) -> dict:
# 获取窗口状态
@retry(max_retries=3, delay=1.0, backoff=1.0)
def bit_browser_status(self, pk: str, bit_port: str = "54345") -> dict:
"""
通用异步请求方法
:param method: HTTP方法 (GET, POST, PUT, DELETE)
:param endpoint: API接口地址
:param kwargs: 其他请求参数 (json, params等)
:return: 返回JSON数据
"""
if params:
# 将布尔值转换为字符串或整数
params = {k: str(v).lower() if isinstance(v, bool) else v for k, v in params.items()}
async with aiohttp.ClientSession() as session:
async with session.request(method, url, params=params, **kwargs) as response:
return await response.json()
# 创建比特币浏览器
@async_retry(max_retries=3, delay=1.0, backoff=1.0)
async def _bit_browser_create(self, remark: str = '指纹浏览器', ua: str = None, host: str = None, port: str = None,
proxy_user: str = None,
proxy_pwd: str = None, proxy_type: str = 'noproxy', urls: str = None,
bit_port: str = "54345") -> str:
"""
创建比特币浏览器
:param urls: 额外打开的url (可选) 多个用,分割
:param remark: 备注 (可选)
:param bit_port: 可选默认54345
:return: 返回浏览器ID
"""
url = f"{self.bit_host}:{bit_port}/browser/update"
headers = {'Content-Type': 'application/json'}
data = {
'name': f'{remark if len(remark) < 40 else remark[:40]}', # 窗口名称
'remark': f'{remark}', # 备注
'proxyType': f'{proxy_type}',
"browserFingerPrint": {"userAgent": ua} # 留空,随机指纹
}
if host is not None:
data['host'] = host
if port is not None:
data['port'] = port
if proxy_user is not None:
data['proxyUserName'] = proxy_user
if proxy_pwd is not None:
data['proxyPassword'] = proxy_pwd
if urls is not None:
data['url'] = urls # 额外打开的url 多个用,分割
res = await self.__request('POST', url, json=data, headers=headers)
if not res.get('success'):
raise Exception(res)
browser_pk = res['data']['id']
return browser_pk
# 修改比特币浏览器
@async_retry(max_retries=3, delay=1.0, backoff=1.0)
async def _bit_browser_update(self, pk: str, remark: str = None, proxyType: str = 'noproxy', host: str = None,
port: str = None, proxy_user: str = None, proxy_pwd: str = None, urls: str = None,
bit_port: str = "54345") -> bool:
"""
修改比特币浏览器 传入某个参数则修改某个参数
:param pk: # 浏览器ID
:param remark: # 备注
:param urls: # 额外打开的url 多个用,分割
:param bit_port: # 可选默认54345
:return:
"""
url = f"{self.bit_host}:{bit_port}/browser/update/partial"
headers = {'Content-Type': 'application/json'}
data = dict()
data['ids'] = [pk]
if remark is not None:
data['remark'] = remark
data['name'] = remark
if urls is not None:
data['url'] = urls
if proxyType != 'noproxy':
data['proxyType'] = proxyType
if host is not None:
data['host'] = host
if port is not None:
data['port'] = port if isinstance(port, int) else int(port)
if proxy_user is not None:
data['proxyUserName'] = proxy_user
if proxy_pwd is not None:
data['proxyPassword'] = proxy_pwd
res = await self.__request('POST', url, json=data, headers=headers)
if not res.get('success'):
raise Exception(res)
return True
# 打开比特币浏览器
@async_retry(max_retries=3, delay=1.0, backoff=1.0)
async def _bit_browser_open(self, pk: str, bit_port: str = "54345") -> str:
"""
打开比特币浏览器
获取比特浏览器窗口状态
:param pk: 浏览器ID
:param bit_port: 可选默认54345
:return: 返回浏览器地址
:return: {'success': True, 'data': {'id': '12a3126accc14c93bd34adcccfc3083c', 'name': '12a3126accc14c93bd34adcccfc3083c', 'remark': '12a3126accc14c93bd34adcccfc3083c', '
"""
url = f"{self.bit_host}:{bit_port}/browser/open"
data = {"id": f'{pk}'}
url = f"{self.bit_host}:{bit_port}/browser/pids"
headers = {'Content-Type': 'application/json'}
res = await self.__request('POST', url, json=data, headers=headers)
data = {'ids': [pk]}
res = requests.post(url, json=data, headers=headers).json()
# print(f'res --> {res}')
if not res.get('success'):
raise Exception(res)
debugger_address = res['data']['http']
return debugger_address
# 关闭比特币浏览器
async def _bit_browser_close(self, pk: str, bit_port: str = "54345"):
"""
关闭比特币浏览器 - 执行后需要等待5s
:param pk: 浏览器ID
:param bit_port: 可选默认54345
:return: 无返回值
"""
url = f"{self.bit_host}:{bit_port}/browser/close"
headers = {'Content-Type': 'application/json'}
data = {'id': f'{pk}'}
await self.__request('POST', url, json=data, headers=headers)
await asyncio.sleep(5) # 等待5s等待浏览器关闭
# 删除比特币浏览器
async def _bit_browser_delete(self, pk: str, bit_port: str = "54345"):
"""
删除比特币浏览器
:param pk: 浏览器ID
:param bit_port: 可选默认54345
:return: 无返回值
"""
url = f"{self.bit_host}:{bit_port}/browser/delete"
headers = {'Content-Type': 'application/json'}
data = {'id': f'{pk}'}
print(await self.__request('POST', url, json=data, headers=headers))
# 获取所有比特币浏览器
@async_retry(max_retries=3, delay=1.0, backoff=1.0)
async def _bit_browser_get(self, page: int = 0, limit: int = 10, group_id: str | None = None,
bit_port: str | None = "54345",
) -> dict:
"""
获取所有比特币浏览器
:param page: 页码
:param group_id: 分组ID
:param limit: 每页数量
:param bit_port: 可选默认54345
:return: {'success': True, 'data': {'page': 1, 'pageSize': 10, 'totalNum': 128, 'list': [{'id': '12a3126accc14c93bd34adcccfc3083c'},{'id':'edc5d61a56214e9f8a8bbf1a2e1b405d'}]}}
"""
url = f"{self.bit_host}:{bit_port}/browser/list"
headers = {'Content-Type': 'application/json'}
data = {'page': page, 'pageSize': limit}
if group_id is not None:
data['groupId'] = group_id
res = await self.__request('POST', url, json=data, headers=headers)
if not res.get('success'):
raise Exception(res)
return res
# 获取比特浏览器窗口详情
@async_retry(max_retries=3, delay=1.0, backoff=1.0)
async def _bit_browser_detail(self, pk: str, bit_port: str = "54345") -> dict:
"""
获取比特浏览器窗口详情
:param pk: 浏览器ID
:param bit_port: 可选默认54345
:return: {'success': True, 'data': {'id': '12a3126accc14c93bd34adcccfc3083c', 'name': '12a3126accc14c93bd34adcccfc3083c', 'remark': '12a3126accc14c93bd34adcccfc3083c', 'groupId': '12a3126accc14c93bd34adcccfc3083c', 'proxyType
"""
url = f"{self.bit_host}:{bit_port}/browser/detail"
headers = {'Content-Type': 'application/json'}
data = {
"id": pk
}
res = await self.__request('POST', url, json=data, headers=headers)
if not res.get('success'):
raise Exception(res)
return res
# 获取比特浏览器的进程id并杀死进程
@async_retry(max_retries=3, delay=1.0, backoff=1.0)
async def _bit_browser_kill_pid(self, pk: str, bit_port: str = "54345") -> str:
"""
获取比特浏览器的进程id
:param pk: 浏览器ID
:param bit_port: 可选默认54345
:return: 返回进程id
"""
url = f"{self.bit_host}:{bit_port}/browser/pids/alive"
headers = {'Content-Type': 'application/json'}
data = {
"ids": [pk]
}
res = await self.__request('POST', url, json=data, headers=headers)
if not res.get('success'):
raise Exception(res)
pid = res['data'][pk]
# 检测系统 并杀死进程
if pid is not None:
if os.name == 'nt':
os.system(f"taskkill /F /PID {pid}")
else:
os.system(f"kill -9 {pid}")
return pid
if res.get('data').get(pk) is None:
return False
else:
return True
async def main():
bit = BitBrowser()