Exemple #1
0
class RunSpider(object):
    def __init__(self):
        self.pool = Pool()
        self.proxy_pool = MongoPool()

    def _auto_import_instances(self):
        """根据配置信息, 自动导入爬虫"""
        instances = []
        # 遍历配置的爬虫, 获取爬虫路径
        for path in settings.PROXIES_SPIDERS:
            # 根据路径, 获取模块名 和 类名
            module_name, cls_name = path.rsplit('.', maxsplit=1)
            # 根据模块名导入模块
            module = importlib.import_module(module_name)
            # 根据类名, 从模块中, 获取爬虫类
            cls = getattr(module, cls_name)
            # 创建爬虫对象, 添加到列表中
            instances.append(cls())

        # 返回爬虫对象列表
        return instances

    def run(self):
        """启动爬虫"""
        # 获取代理爬虫
        spiders = self._auto_import_instances()
        # 执行爬虫获取代理
        for spider in spiders:
            # 使用协程异步调用该方法,提高爬取的效率
            self.pool.apply_async(self.__run_one_spider, args=(spider, ))

        # 等待所有爬虫任务执行完毕
        self.pool.join()

    def __run_one_spider(self, spider):
        try:
            for proxy in spider.get_proxies():
                if proxy is None:
                    # 如果是None继续一个
                    continue
                # 检查代理, 获取代理协议类型, 匿名程度, 和速度
                proxy = check_proxy(proxy)
                # 如果代理速度不为-1, 就是说明该代理可用
                if proxy.speed != -1:
                    # 保存该代理到数据库中
                    self.proxy_pool.save(proxy)
        except Exception as e:
            logger.exception(e)
            logger.exception("爬虫{} 出现错误".format(spider))

    @classmethod
    def start(cls):
        # 创建本类对象
        run_spider = RunSpider()
        run_spider.run()

        # 每隔 SPIDER_INTERVAL 小时检查下代理是否可用
        schedule.every(settings.SPIDER_INTERVAL).hours.do(run_spider.run())
        while True:
            schedule.run_pending()
            time.sleep(1)
Exemple #2
0
class RunSpiders(object):
    """
    启动各个爬虫
    """
    def __init__(self):
        """
        创建协程池及数据库操作对象
        """
        self.pool = Pool()
        self.proxy_pool = MongoPool()

    @staticmethod
    def _import_spider_instance():
        """
        动态导入各爬虫模块并创建爬虫对象
        :return:
        """
        # 存放爬虫对象
        instances = []
        # 依次导入各爬虫模块并创建爬虫对象
        for instance_path in PROXIES_SPIDERS:
            # 获取爬虫模块路径及爬虫类名称
            module_name, class_name = instance_path.rsplit('.', maxsplit=1)
            # 导入模块
            module = importlib.import_module(module_name)
            # 获取模块中的爬虫对象
            _class = getattr(module, class_name)
            # 创建爬虫对象,并加入爬虫列表中
            instances.append(_class())
        return instances

    def _run_spider(self, spider):
        """
        开启爬虫
        :param spider:
        :return:
        """
        try:
            # 获取代理ip数据
            for proxy in spider.get_proxies():
                if proxy is None:
                    continue
                # 检测此代理ip
                proxy = check_proxy(proxy)
                # 判断此代理ip是否有效
                if proxy.speed != -1:
                    # 将此代理ip保存到数据库中
                    self.proxy_pool.save(proxy)
        except Exception as e:
            logger.exception("爬虫{}出错,原因:{}".format(spider, e))

    def run(self):
        """
        将各个爬虫加入到协程池中,并启动
        :return:
        """
        # 导入爬虫模块,并创建对象
        spiders = self._import_spider_instance()
        # 将各个爬虫加入到协程池中
        for spider in spiders:
            # 异步非阻塞
            self.pool.apply_async(self._run_spider, args=(spider, ))
        # 让主线程等待异步任务完成
        self.pool.join()

    @classmethod
    def start(cls):
        """
        开启爬虫服务
        :return:
        """
        # 创建并启动爬虫
        spiders = cls()
        spiders.run()

        # 设置定时启动爬虫
        schedule.every(SPIDER_INTERVAL).hours.do(spiders.run)
        while True:
            # 运行任务
            schedule.run_pending()
            time.sleep(1)