Пример #1
0
    def load_any_subscribe(self, api: Chrome, element_xpath_str: str, href_xpath_str: str, class_: str, retry=0):
        """
        捕获订阅并送入持久化数据池
        @param api: ChromeDriverObject
        @param element_xpath_str: 用于定位链接所在的标签
        @param href_xpath_str: 用于取出目标标签的属性值,既subscribe
        @param class_: 该subscribe类型,如`ssr`/`v2ray`/`trojan`
        @param retry: 失败重试
        @todo 使用 retrying 模块替代retry参数实现的功能(引入断网重连,断言重试,行为回滚...)
        @return:
        """
        self.subscribe = WebDriverWait(api, 30).until(expected_conditions.presence_of_element_located((
            By.XPATH,
            element_xpath_str
        ))).get_attribute(href_xpath_str)

        # 若对象可捕捉则解析数据并持久化数据
        if self.subscribe:
            # 失败重试3次
            for x in range(3):
                # ['domain', 'subs', 'class_', 'end_life', 'res_time', 'passable','username', 'password', 'email']
                try:
                    # 机场域名
                    domain = urlparse(self.register_url).netloc
                    # 采集时间
                    res_time = str(datetime.now(TIME_ZONE_CN)).split('.')[0]
                    # 链接可用,默认为true
                    passable = 'true'
                    # 信息键
                    docker = [domain, self.subscribe, class_, self.end_life, res_time, passable, self.username,
                              self.password, self.email]
                    # 根据不同的beat_sync形式持久化数据
                    FlexibleDistribute(docker=docker, beat_sync=self.beat_sync)
                    # 数据存储成功后结束循环
                    logger.success(">> GET <{}> -> {}:{}".format(self.action_name, class_, self.subscribe))
                    # TODO ADD v5.1.0更新特性,记录机场域名-订阅域名映射缓存
                    # set_task2url_cache(task_name=self.__class__.__name__, register_url=self.register_url,
                    #                    subs=self.subscribe)
                    break
                except Exception as e:
                    logger.debug(">> FAILED <{}> -> {}:{}".format(self.action_name, class_, e))
                    time.sleep(1)
                    continue
            # 若没有成功存储,返回None
            else:
                return None
        # 否则调入健壮工程
        # TODO 判断异常原因,构建解决方案,若无可靠解决方案,确保该任务安全退出
        else:
            if retry >= 3:
                raise TimeoutException
            retry += 1
            self.load_any_subscribe(api, element_xpath_str, href_xpath_str, class_, retry)
Пример #2
0
    def run(beat_sync=True, force_run=None) -> None:
        """
        本地运行--检查队列残缺
        # 所有类型任务的节点行为的同时发起 or 所有类型任务的节点行为按序执行,node任务之间互不影响

            --v2rayChain
                --vNode_1
                --vNode_2
                --....
            --ssrChain
                --sNode_1
                --sNode_2
                --...
            --..
                                    -----> runtime v2rayChain
        IF USE vsu -> runtime allTask =====> runtime ...
                                    -----> runtime ssrChain

            ELSE -> runtime allTask -> Chain_1 -> Chain_2 -> ...

                                    -----> runtime node_1
        IF USE go -> runtime allNode =====> runtime ...
                                    -----> runtime node_N

            ELSE -> runtime allNode-> the_node_1 -> the_node_2 -> ...

        @return:
        """
        # 同步任务队列(广度优先)
        # 这是一次越权执行,无论本机是否具备collector权限都将执行一轮协程空间的创建任务
        for class_ in CRAWLER_SEQUENCE:
            sailor.manage_task(class_=class_,
                               beat_sync=beat_sync,
                               force_run=force_run)

        # FIXME 节拍同步
        if not beat_sync:
            from src.BusinessCentralLayer.middleware.subscribe_io import FlexibleDistribute
            FlexibleDistribute().start()

        # 执行一次数据迁移
        # TODO 将集群接入多哨兵模式,减轻原生数据拷贝的额外CPU资源开销
        _cd.startup_ddt_overdue()

        # 任务结束
        logger.success('<Gevent>任务结束')