diff --git a/spider/111.py b/spider/111.py new file mode 100644 index 0000000..d2a0f8d --- /dev/null +++ b/spider/111.py @@ -0,0 +1,139 @@ +from math import log +import random +from re import S +import time +from tkinter import N +from DrissionPage import Chromium +from loguru import logger +from work import get_random_canada_info +from mail_ import mail_ +from bit_browser import bit_browser +from api import api + + +class Auto: + def __init__(self, http: str = None): + self.browser = Chromium(http) + self.tab = self.browser.latest_tab + pass + + # cf打码 + def solve_cloudflare(self, is_ok: bool = False): + tab = self.browser.latest_tab + for _ in range(5): + tab.wait(1) + res = tab.ele( + 't:h1@text()=Sorry, you have been blocked', timeout=1) + if res: + logger.error("Cloudflare验证失败") + return False + + try: + shadow1 = tab.ele( + 'x://*[@name="cf-turnstile-response"]').parent().shadow_root + iframe = shadow1.get_frame(1) + if iframe: + logger.debug("找到Cloudflare iframe") + shadow2 = iframe.ele('x:/html/body').shadow_root + if shadow2: + logger.debug("找到Cloudflare iframe body shadow root") + status = shadow2.ele( + 'x://span[text()="Verifying..."]', timeout=1.5) + if status: + logger.debug("Cloudflare验证中,等待3秒") + tab.wait(3) + status = shadow2.ele( + 'x://span[text()="Success!"]', timeout=1.5) + if status: + logger.debug("Cloudflare验证成功") + return True + checkbox = shadow2.ele( + 'x://input[@type="checkbox"]', timeout=1.5) + if checkbox: + logger.debug("点击Cloudflare复选框") + checkbox.click() + tab.wait(3) + logger.debug("重新获取状态") + # return False + except Exception as e: + # logger.error(f"处理Cloudflare异常: {e}") + if is_ok: + logger.debug(f"cloudflare处理通过: {e}") + return True + return self.solve_cloudflare(is_ok=True) + tab.wait(1) + return False + + def wait_home(self): + logger.debug("等待进入首页") + jc = 0 + while True: + if jc > 3: + logger.error("等待进入首页超过5次,未成功") + return False + self.tab.wait(1) + # 判断cf是否通过 + bol = self.solve_cloudflare() + if not bol: + logger.debug("Cloudflare验证失败.") + # 刷新网页 + self.tab.refresh() + self.tab.wait(1.5) + jc += 1 + continue + else: + logger.debug("Cloudflare验证成功.") + self.tab.wait(1.5) + bol = self.tab.ele( + 't:h1@text()=Sorry, you have been blocked', timeout=1) + if bol: + logger.debug("ip被ban秒") + return False + + bol = self.tab.ele( + 't:div@text():ERR_TIMED_OUT', timeout=1) + if bol: + logger.debug("刷新网页") + self.tab.refresh() + self.tab.wait(1.5) + bol = self.tab.ele( + 't:div@text():ERR_SSL_PROTOCOL_ERROR', timeout=1) + if bol: + logger.debug("刷新网页") + self.tab.refresh() + self.tab.wait(1.5) + bol = self.tab.ele( + 't:div@text():ERR_SOCKS_CONNECTION_FAILED', timeout=1) + if bol: + logger.debug("刷新网页") + self.tab.refresh() + self.tab.wait(1.5) + html = self.tab.url + logger.debug(f"当前URL: {html}") + if 'https://veritaconnect.ca/canadianbreadsettlement/en-us' == html: + logger.debug("成功进入首页") + return True + jc += 1 + + def open_url(self, url: str): + self.tab.get(url) + + +def main(): + browser_id = bit_browser.bit_browser_create( + remark=f"us.novproxy.io:1000:ozua8623-region-CA-st-Ontario-city-Toronto:6wdcv4gq", + host="us.novproxy.io", + port=1000, + proxy_user="ozua8623-region-CA-st-Alberta-city-Calgary", + proxy_pwd="6wdcv4gq", + proxy_type='socks5' + ) + http = bit_browser.bit_browser_open(browser_id) + logger.debug(f"打开浏览器 {browser_id}, http: {http}") + auto = Auto(http) + auto.open_url( + "https://veritaconnect.ca/canadianbreadsettlement/en-us/Claimant/UnknownClaimForm") + auto.wait_home() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/spider/bit_browser.py b/spider/bit_browser.py index df039c6..1ec217e 100644 --- a/spider/bit_browser.py +++ b/spider/bit_browser.py @@ -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()