Beispiel #1
0
class ProxyTest(object):
    """
    测试代理ip可用性
    """
    def __init__(self):
        """
        初始化进程池、队列及数据库操作对象
        """
        self.pool = Pool()
        self.queue = Queue()
        self.mongo_pool = MongoPool()

    def _test_proxies(self):
        """
        测试代理ip可用性,并更新到数据库
        :return:
        """
        # 从队列中取出一个代理ip
        proxy = self.queue.get()
        try:
            # 检测代理ip
            proxy = check_proxy(proxy)
            # 判断此代理ip此次是否有效,若有效则恢复为默认分值,否则分值减1
            if proxy.speed == -1:
                proxy.score -= 1
                # 若评分为0,则表示此代理ip不可用,则从数据库中删除此代理ip
                if proxy.score == 0:
                    self.mongo_pool.delete(proxy)
                else:
                    # 更新此代理ip
                    self.mongo_pool.update(proxy)
            else:
                # 此代理ip恢复为默认分值
                proxy.score = DEFAULT_SCORE
                # 更新此代理ip
                self.mongo_pool.update(proxy)
        except Exception as e:
            print(e)

    def _test_callback(self, source):
        """
        检测代理ip(_test_proxies)的回调函数
        :param source: 回调函数所需参数
        :return:
        """
        # 使其死循环,不断检测代理ip
        self.pool.apply_async(self._test_proxies, callback=self._test_callback)

    def run(self):
        """
        启动代理ip的检测
        :return:
        """
        # 从数据库中获取所有代理ip
        proxies = self.mongo_pool.find()
        # 判断是否有代理ip
        if proxies is None or len(proxies) == 0:
            print("代理ip池为空")
            return

        # 依次将代理ip添加到队列中
        for proxy in proxies:
            self.queue.put(proxy)

        # 开启若干进程,用于检测代理ip
        for test in range(TEST_ANSYC_COUNT):
            # 异步非阻塞
            self.pool.apply_async(self._test_proxies,
                                  callback=self._test_callback)

        # 让主线程等待异步任务完成
        self.pool.join()

    @classmethod
    def start(cls):
        """
        开启检测代理ip服务
        :return:
        """
        # 创建并启动检测
        test = cls()
        test.run()

        # 定时启动检测
        schedule.every(TEST_INTERVAL).hours.do(test.run)
        while True:
            # 运行任务
            schedule.run_pending()
            time.sleep(1)
Beispiel #2
0
class ProxyTester(object):
    def __init__(self):
        self.queue = Queue()
        self.pool = Pool() # 协程池
        self.proxy_pool = MongoPool() # 基于MongoDB的代理池

    def _test_proxy(self):
        # 从代理队列中, 获取请求
        proxy = self.queue.get()
        try:
            # 验证当前的代理
            proxy = check_proxy(proxy)
            # 如果速度为-1就说明请求失败了
            if proxy.speed == -1:
                # 代理的分数-1
                proxy.score -= 1

                # 如果分数为0, 就删除该代理
                if proxy.score == 0:
                    self.proxy_pool.delete(proxy)
                    logger.info('删除代理:{}'.format(proxy))
                else:
                    # 如果分数不为0 ,就更新当前的代理
                    self.proxy_pool.update(proxy)
            else:
                # 如果请求成功了, 恢复为最高分数
                proxy.score = settings.MAX_SCORE
                self.proxy_pool.update(proxy)

        except Exception as ex:
            logger.exception(ex)

        self.queue.task_done()

    def _test_proxy_finish(self, temp):
        self.pool.apply_async(self._test_proxy, callback=self._test_proxy_finish)

    def run(self):
        # 1. 获取所有代理IP
        proxies = self.proxy_pool.find()
        # 2. 如果代理池为空, 直接返回
        if proxies is None or len(proxies) == 0:
            print("代理池为空")
            return

        # 获取所有的代理, 放到队列中
        for proxy in proxies:
            self.queue.put(proxy)

        # 开启多个异步任务执行检查IP的任务
        for i in range(settings.TESTER_ANSYC_COUNT):
            self.pool.apply_async(self._test_proxy,callback=self._test_proxy_finish)

        # 让主线程等待异步任务完成
        self.queue.join()

    @staticmethod
    def start():
        tester = ProxyTester()
        tester.run()
        # 每隔2小时检查下代理是否可用
        schedule.every(settings.TESTER_INTERVAL).hours.do(tester.run)
        while True:
            schedule.run_pending()
            time.sleep(1)