class RunSpider(object): def __init__(self): # 创建mongopool对象 self.mongo_pool = MongoPool() # 创建协程池 self.coroutine_pool = Pool() def get_spider_from_settings(self): ''' 根据配置文件获取爬虫对象列表, :return: ''' # 遍历文件爬虫的全类名 for full_class_name in PROXIES_SPIDERS: # 获取模块名和类名 module_name, class_name = full_class_name.rsplit('.', maxsplit=1) # print(full_class_name.rsplit('.', maxsplit=1)) # 根据模块名导入模块 module = importlib.import_module(module_name) # 根据类名,从模块中获取类 cls = getattr(module, class_name) spider = cls() # print(spider) yield spider def run(self): # 根据配置文件获取爬虫对象列表, spiders = self.get_spider_from_settings() for spider in spiders: # 异步调用执行的方法 self.coroutine_pool.apply_async(self._execute_one_spider_task, args=(spider,)) # 调用协程的join,让当前线程等待 协程的任务完成 self.coroutine_pool.join() def _execute_one_spider_task(self, spider): # 用于处理爬虫的方法 try: # 遍历爬虫对象的方法 for proxy in spider.get_proxies(): # print(proxy) # 检测代理可用性 proxy = check_proxy(proxy) # 如果speed不为-1 就说明可用 if proxy.speed != -1: self.mongo_pool.insert_one(proxy) except Exception as ex: logger.exception(ex) @classmethod def start(cls): rs = RunSpider() rs.run() # 每间隔多长时间进行一次执行 # settings里面配置 schedule.every(RUN_SPIDERS_INTERVAL).hours.do(rs.run) while True: # 检测时间 每隔一秒钟检查一次是否到了时间 schedule.run_pending() time.sleep(1)
class RunSpider(object): def __init__(self): self.mongo_pool = MongoPool() self.coroutine_pool = Pool() def get_spider_from_settings(self): for full_class_name in PROXIES_SPIDERS: module_name, class_name = full_class_name.rsplit('.', maxsplit=1) module = importlib.import_module(module_name) cls = getattr(module, class_name) spider = cls() yield spider def run(self): spiders = self.get_spider_from_settings() for spider in spiders: # self.__execute_one_spider_task(spider) self.coroutine_pool.apply_async(self.__execute_one_spider_task, args=(spider, )) self.coroutine_pool.join() def __execute_one_spider_task(self, spider): try: for proxy in spider.get_proxies(): proxy = check_proxy(proxy) if proxy.speed != -1: self.mongo_pool.insert_one(proxy) except Exception as ex: logger.exception(ex)
class RunSpider(object): def __init__(self): #在init中,建立数据连接,获取要操作的集合 self.mongo_pool=MongoPool() # 在init方法中创建协程池对象 self.coroutine_pool=Pool() def get_spider_from_settings(self): #根据配置文件信息,获取爬虫对象列表 #遍历配置文件中爬虫信息,获取每个爬虫全类名 for full_class_name in PROXIES_SPIDERS: #core.proxy_spider.proxy_spiders.XiciSpider #获取模块名 和 类名 module_name, class_name = full_class_name.rsplit('.', maxsplit=1) # 根据模块名,导入模块 module = importlib.import_module(module_name) # 根据类名,从模块中,获取类 cls = getattr(module, class_name) # 3创建爬虫对象 spider = cls() print(spider, "666") yield spider def run(self): #根据配置文件信息,获取爬虫对象列表, spiders=self.get_spider_from_settings() # 遍历爬虫对象列表,获取爬虫对象,遍历爬虫对象的get_proxies方法,获取IP for spider in spiders: # 使用异步执行这个方法 # self._execute_one_spider_task(spider) self.coroutine_pool.apply_async(self._execute_one_spider_task,args=(spider,)) # 调用协程的join方法,让当前线程等待 协程 任务完成 self.coroutine_pool.join() # 把处理一个代理爬虫的代码抽到一个方法,用于处理一个爬虫任务的 def _execute_one_spider_task(self, spider): try: for proxy in spider.get_proxies(): # print(proxy) # 检验代理IP(代理ip检验模块) proxy = check_proxy(proxy) # 如果可用,写入数据库(数据库模块),如果speed不为-1,就说明可用 if proxy.speed != -1: # 写入数据库(数据库模块) self.mongo_pool.insert_one(proxy) except Exception as ex: logger.exception(ex) @classmethod def start(cls): # 1,定义一个start的类方法 # 2,创建当前类的对象,调用run方法 rs=RunSpider() rs.run() # 3,使用schedule模块,每隔一定时间,执行当前对象的run方法 #修改配置文件,增加爬虫运行时间间隔的配置,单位为小时 schedule.every(RUN_SPIDERS_INTERVAL).hours.do(rs.run) while True: schedule.run_pending() time.sleep(2)
class RunSpider(object): def __init__(self): # 创建MongoPool对象 self.mongo_pool = MongoPool() # 3.1 在init方法中创建协程池对象 self.coroutine_pool = Pool() def get_spider_from_settings(self): """根据胚子文件信息, 获取爬虫对象列表""" # 首先遍历配置文件中的爬虫信息, 获取每个爬虫全类名 for full_class_name in PROXIES_SPIDERS: # core.proxy_spider.proxy_spiders.Ip66Spider # 获取模块名和类名,然后根据模块名动态创建类对象 module_name, class_name = full_class_name.rsplit('.', maxsplit=1) # 根据模块名导入模块 module = importlib.import_module(module_name) # 根据模块获取爬虫对象 cls = getattr(module, class_name) # 创建爬虫对象 spider = cls() yield spider def run(self): # 2.1 根据配置文件信息,获取爬虫对象列表 spiders = self.get_spider_from_settings() for spider in spiders: # 2.2 遍历爬虫对象列表, 获取爬虫对象, 遍历爬虫对象的get_proxies方法, 获取代理IP # self._execute_one_spider_task(spiders) # 抽取出的方法使用线程池调度 self.coroutine_pool.apply_async(self._execute_one_spider_task, args=(spider, )) # 3.4 调用协程的 join方法, 让当前线程等待协程任务的完成 self.coroutine_pool.join() def _execute_one_spider_task(self, spider): try: # 遍历爬虫对象的get_proxies方法, 获取代理IP for proxy in spider.get_proxies(): # 2.3 检测代理IP(代理IP检测模块) proxy = check_proxy(proxy) # 如果速度不为-1, 说明可用 if proxy.speed != -1: # 写入数据库 self.mongo_pool.insert_one(proxy) except Exception as e: logger.exception(e) @classmethod def start(cls): cls().run() schedule.every(SPIDER_TIME_DELAY).hours.do(cls().run) while True: schedule.run_pending() time.sleep(1)
class RunSpider(object): spider_list = [ 'kuaiSpider', 'jiangxianSpider', 'xilaSpider', 'xiaohuanSpider', 'zhimaSpider', 'nimaSpider', 'qiyunSpider', 'spider89', ] module_name = 'core.proxy_spider.proxy_spiders' def __init__(self, module_name='', spider_list=[]): if module_name: self.module_name = module_name if spider_list: self.spider_list = spider_list self.mongo_pool = MongoPool() #创建协程池 self.coroutine_pool = Pool() def get_spider_cls(self, spider_list, module_name): module = importlib.import_module(module_name) for spider_name in spider_list: spider_cls = getattr(module, spider_name) yield spider_cls def run_spider(self): for spider in self.get_spider_cls(self.spider_list, self.module_name): #self.__execute_one_spider_task(spider) self.coroutine_pool.apply_async(self.__execute_one_spider_task, args=(spider, )) self.coroutine_pool.join() def __execute_one_spider_task(self, spider): try: for proxy in spider.get_proxies(): proxy = check_proxy(proxy) if proxy.delay != -1: self.mongo_pool.insert_one(proxy) print("新代理插入成功" + dict(proxy)) except Exception as ex: logger.exception(ex) @classmethod def start(cls): rs = RunSpider() rs.run_spider() schedule.every(RUN_SPIDER_INTERVAL).hours.do(rs.run_spider) while True: schedule.run_pending() time.sleep(30)
class RunSpider(object): def __init__(self): self.mongo_pool = MongoPool() #创建协程池对象 self.coroutine_pool = Pool() def get_spider_from_settings(self): """根据配置文件信息,获取爬虫对象列表""" #遍历配置文件中爬虫信息,获取每个爬虫全类名 for full_class_name in PROXIES_SPIDERS: #获取模块名和类名 module_name, class_name = full_class_name.rsplit('.', maxsplit=1) #根据模块名,导入模块 module = importlib.import_module(module_name) # #根据类名,从模块中,获取类 cls = getattr(module, class_name) #创建爬虫对象 spider = cls() # print(spider) yield spider def run(self): # 根据配置文件信息,获取爬虫对象列表 spiders = self.get_spider_from_settings() for spider in spiders: #把处理一个代理爬虫的代码抽到一个方法用于处理一个爬虫任务 # self.__execute_one_spider_task(spider) self.coroutine_pool.apply_async(self.__execute_one_spider_task, args=(spider, )) #调用协程的join方法,让当前线程等待协程任务的未完成 self.coroutine_pool.join() def __execute_one_spider_task(self, spider): try: for proxy in spider.get_proxies(): # 检测代理IP(调用检测模块) proxy = check_proxy(proxy) # 如果可用,写入数据库(调用数据库模块,speed不为-1就说明可用) if proxy.speed != -1: self.mongo_pool.insert_one(proxy) # print(proxy) except Exception as ex: logger.exception(ex) @classmethod def start(cls): rs = RunSpider() rs.run() #每间隔多少个小时运行爬虫 schedule.every(RUN_SPIDERS_INTERVAL).hours.do(rs.run) while True: schedule.run_pending() time.sleep(1)
class RunSpider(object): def __init__(self): self.mongo_pool = MongoPool() # 创建携程池对象 self.coroutine_pool = Pool() @staticmethod def get_spiders_from_settings(self): for spider_full_path in PROXY_SPIDERS: module_name, class_name = spider_full_path.rsplit('.', maxsplit=1) # 根据已经获得的module_name动态导入模块 module = importlib.import_module(module_name) # 根据类名,从模块中获取类 cls = getattr(module, class_name) # 创建爬虫对象 spider = cls() yield spider def __execute_one_spider_task(self, spider): try: for proxy in spider.get_proxies(): # 检测代理IP可用性 proxy = check_proxy(proxy) # print(proxy) # 如果可用就入数据库 if proxy.speed != -1: self.mongo_pool.insert_one(proxy) except Exception as e: logger.exception(e) def run(self): spiders = self.get_spiders_from_settings() for spider in spiders: self.coroutine_pool.apply_async(self.__execute_one_spider_task, args=(spider,)) # self.__execute_one_spider_task(spider) self.coroutine_pool.join() # 定时调用run方法启动spiders @classmethod def start(cls): r = RunSpider() r.run() logger.info("*****************本次爬取完毕,等待下次爬取*****************") schedule.every(RUN_SPIDERS_INTERVAL).hours.do(r.run) while True: schedule.run_pending() time.sleep(RUN_SPIDERS_INTERVAL * 60 * 60 / 2 + 1)
class RunSpider(object): def __init__(self): self.mongo_pool = MongoPool() self.corutine_pool = Pool() def get_spider_from_settings(self): # 遍历配置文件,获取信息 for spider in PROXY_SPIDERS: # 获取模块名 类名 module_name, class_name = spider.rsplit('.', maxsplit=1) # 根据模块名导入类名 module = importlib.import_module(module_name) # 根据类名,从模块中获取类 cls = getattr(module, class_name) # 创建对象 spider = cls() yield spider def run(self): spiders = self.get_spider_from_settings() for spider in spiders: # 通过协程池异步执行 self.corutine_pool.apply_async(self.__execute_one_spider, args=(spider, )) self.corutine_pool.join() # 处理一个爬虫的 def __execute_one_spider(self, spider): try: for proxy in spider.get_proxies(): proxy = check_proxy(proxy) if proxy.speed != -1: self.mongo_pool.insert_one(proxy) except Exception as e: logger.error(e) @classmethod def start(self): rs = RunSpider() rs.run() schedule.every(RUN_SPIDERS_INTERVAL).hours.do(rs.run()) while True: schedule.run_pending()
class RunSpider(object): def __init__(self): self.mongo_pool = MongoPool() self.coroutine_pool = Pool() def run(self): spiders = self.get_spider_from_settings() for spider in spiders: #异步的方式 self.coroutine_pool.apply_async(self._execute_one_spider, args=(spider, )) self.coroutine_pool.join() def _execute_one_spider(self, spider): try: for proxy in spider.get_proxies(): # 检验ip proxy = check_proxy(proxy) # speed=-1不可以 if proxy.speed != -1: self.mongo_pool.insert_one(proxy) except Exception as ex: logger.exception(ex) def get_spider_from_settings(self): # 根据配置文件获取爬虫列表 for full_class_name in PROXIES_SPIDERS: #获取模块名和类名 module_name, class_name = full_class_name.rsplit('.', maxsplit=1) #根据模块名导入模块 ---->import proxy_spider module = importlib.import_module(module_name) #根据类名,从模块中获取类---->from proxy_spider import ProxylistplusSpider, cls = getattr(module, class_name) spider = cls() yield spider @classmethod def start(cls): r = RunSpider() r.run() schedule.every(RUN_SPIDERS_INTERVAL).hours.do(r.run()) while True: schedule.run_pending() time.sleep(3600)
class RunSpider(object): def __init__(self): self.mongo_pool = MongoPool() # 协程池 self.coroutine_pool = Pool() def get_spider_from_config(self): for full_class_name in PROXIES_SPIDERS: # 获取模块名和类名 module_name, class_name = full_class_name.rsplit('.', maxsplit=1) module = importlib.import_module(module_name) cls = getattr(module, class_name) spider = cls() yield spider def run(self): spiders = self.get_spider_from_config() for spider in spiders: # self.__execute_one_spider_task(spider) self.coroutine_pool.apply_async(self.__execute_one_spider_task, args=(spider, )) self.coroutine_pool.join() def __execute_one_spider_task(self, spider): try: for proxy in spider.get_proxies(): proxy = check_proxy(proxy) print(proxy) if proxy.speed != -1: self.mongo_pool.insert_one(proxy) except Exception as ex: pass @classmethod def start(cls): rs = RunSpider() rs.run() # 4.3.1 配置文件,增加爬虫运行时间间隔的配置,单位为小时 schedule.every(RUN_SPIDERS_INTERVAL).hours.do(rs.run) while True: schedule.run_pending() time.sleep(1)
class RunSpider(object): def __init__(self): self.mongo_pool = MongoPool() self.coroutine_pool = Pool() def get_spider_from_settings(self): for full_name_path in SPIDER_PATH: module_name, class_name = full_name_path.rsplit('.', maxsplit=1) module = importlib.import_module(module_name) cls = getattr(module, class_name) spider = cls() yield spider def run(self): spiders = self.get_spider_from_settings() for spider in spiders: # self._execute_one_task(spider) self.coroutine_pool.apply_async(self._execute_one_task, args=(spider, )) self.coroutine_pool.join() def _execute_one_task(self, spider): try: proxies = spider.get_proxies() for proxy in proxies: proxy = check_proxy(proxy) if proxy.speed != -1: self.mongo_pool.insert_one(proxy) except Exception as e: logger.error(e) @classmethod def start(cls): rs = RunSpider() rs.run() schedule.every(SPIDER_AUTO_INTERVAL).hours.do(rs.run) while True: schedule.run_pending() time.sleep(1)
class RunSpider(object): def __init__(self): self.mongo_pool = MongoPool() self.coroutine_pool = Pool() def get_spiders_from_settings(self): for spider in PROXIES_SPIDERS: module_name, spider_class = spider.rsplit('.', maxsplit=1) module = importlib.import_module(module_name) cls = getattr(module, spider_class) spider = cls() yield spider def run(self): spiders = self.get_spiders_from_settings() for spider in spiders: self.coroutine_pool.apply_async(self.__tasks, args=(spider, )) self.coroutine_pool.join() def __tasks(self, spider): try: proxies = spider.get_proxies() for proxy in proxies: # print(proxy) proxy = check_proxy(proxy) if proxy.idle != -1: self.mongo_pool.insert_one(proxy) except Exception as e: logger.exception(e) @classmethod def start(cls): run_spider = cls() run_spider.run() schedule.every(RUN_SPIDER_INTERVAL).hours.do(run_spider.run) while True: schedule.run_pending() time.sleep(60)
class RunSpider(object): def __init__(self): # 创建MongoPool代理池对象 self.mongo_pool = MongoPool() # 3.1 创建协程池对象 self.coroutine_pool = Pool() def get_spider_from_settings(self): """根据配置文件信息,获取爬虫对象列表(即具体的爬虫类对象列表)""" # 遍历配置文件中的爬虫信息,获取每个爬虫的全类名 for full_class_name in PROXIES_SPIDERS: # 根据全类名信息创建每个爬虫类对象 # 如根据全类名 core.proxy_spider.proxy_spider.XiciSpider # 获取 模块名和类名 module_name, class_name = full_class_name.rsplit( ".", maxsplit=1) # 根据右边的第一个"."进行截取,maxsplit=1表示截取一次 # print(full_class_name.rsplit(".", maxsplit=1)) # ['core.proxy_spider.proxy_spider', 'XiciSpider'] # print(module_name, class_name) # 根据模块名 导入 模块, 动态导入模块 module = importlib.import_module(module_name) # 根据类名,从模块中获取类 cls = getattr(module, class_name) # 根据类,创建爬虫对象 spider = cls() # print(spider) yield spider def run(self): """1. 提供一个运行爬虫的run方法,作为运行爬虫的入口,实现核心的处理逻辑""" # 2.1 根据配置文件信息,获取爬虫对象列表(即具体的爬虫类对象列表) spiders = self.get_spider_from_settings() # 2.2 遍历爬虫对象列表,获取爬虫对象,遍历爬虫对象的get_proxies方法,获取代理IP for spider in spiders: # 2.5 处理异常,防止一个爬虫内部出错,影响其他的爬虫 # self.__execute_one_spider_task(spider) # 3.3 使用异步方式执行这个方法 self.coroutine_pool.apply_async(self.__execute_one_spider_task, args=(spider, )) # 3.4 调用协程的join方法,让当前线程等待 协程 任务的完成 self.coroutine_pool.join() def __execute_one_spider_task(self, spider): """3.2 把处理一个代理爬虫的代码抽取到一个方法中""" try: # 遍历爬虫对象的get_proxies方法,获取代理IP for proxy in spider.get_proxies(): # print(type(proxy), proxy) # 2.3 检测代理IP(代理IP检测模块:httpbin_validator.py) proxy = check_proxy(proxy) # 2.4 如果IP可用,写入数据库(数据库模块: mongo_pool.py) # 如果protocol不等于-1,说明IP可用 if proxy.protocol != -1: # 把可用IP写入到数据库 self.mongo_pool.insert_one(proxy) except Exception as e: # 爬虫报错,记录日志信息 logger.exception(e) # 4.1 定义一个start的类方法 @classmethod def start(cls): # 4.2 创建当前类的对象,调用run方法 rs = RunSpider() rs.run() # 4.3 使用schedule模块,每隔一定的时间,执行当前对象的run方法 # 修改配置文件,配置爬虫运行的时间间隔,单位为小时 schedule.every(RUN_SPIDRS_INTERVAL).hours.do(rs.run) while True: schedule.run_pending() time.sleep(1)
class RunSpider(object): def __init__(self): # 创建MonogPool对象 self.mongo_pool = MongoPool() # 3.1 在init方法中创建协程池对象 self.coroutine_pool = Pool() def get_spider_from_settings(self): # 遍历配置文件中爬虫信息,获取每个爬虫全类名 for full_class_name in PROXIES_SPIDERS: # 'core.proxy_spider.proxy_spiders.XiciSpider' # 获取模块名和类名 module_name, class_name = full_class_name.rsplit('.', maxsplit=1) # 根据模块名,导入模块 module = importlib.import_module(module_name) # 根据类名,从模块中,获取类 cls = getattr(module, class_name) # 创建爬虫对象 spider = cls() yield spider def run(self): # 2.1 根据配置文件信息,获取爬虫对象列表 spiders = self.get_spider_from_settings() # 2.2 遍历爬虫对象列表,获取爬虫对象,遍历爬虫对象的get_proxies方法 for spider in spiders: # 2.5 处理异常,防止一个爬虫内部出错了,影响其他的爬虫 # 3.3 使用异步执行这个方法 # self._execute_one_spider_task(spider) self.coroutine_pool.apply_async(self._execute_one_spider_task, args=(spider, )) # 3.4 调用协程的join方法,让当前线程等待协程任务的完成 self.coroutine_pool.join() # 把处理一个代理爬虫的代码抽到一个方法 def _execute_one_spider_task(self, spider): try: for proxy in spider.get_proxies(): # 2.3 检测代理IP proxy = check_proxy(proxy) # 2.4 如果可用,写入数据库(数据库模块) # 如果speed不为-1,就说明可用 if proxy.speed != -1: # 写入数据库 self.mongo_pool.insert_one(proxy) except Exception as e: logger.exception(e) @classmethod def start(cls): # 4.使用schedule模块,实现每隔一定的时间,执行一个爬取任务 # 4.1 定义一个start的类方法 # 4.2 创建当前类的对象,调用run方法 rs = RunSpider() rs.run() # 4.3 使用schedule模块,每隔一定的时间,执行当前对象的run方法 # 4.3.1 修改配置文件,配置爬虫间隔时间 schedule.every(RUN_SPIDERS_INTERVAL).hours.do(rs.run()) while True: schedule.run_pending() time.sleep(1)
class RunSpider(object): def __init__(self): # 创建MongoPool对象 self.mongo_pool = MongoPool() # 创建协程池对象 self.coroutine_pool = Pool() def get_spider_from_settings(self): # 根据配置文件信息,获取爬虫对象列表 for full_class_name in PROXIES_SPIDER: #'core/proxy_spider/proxy_spiders/XiCiSpiderpy' # 获取模块名 和 类名 module_name, class_name = full_class_name.rsplit('.', maxsplit=1) # 根据模块名,导入模块 module = importlib.import_module(module_name) # 根据类名,从模块中获取类 cls = getattr(module, class_name) spider = cls() yield spider def run(self): # 根据配置文件信息, 获取爬虫对象列表 spiders = self.get_spider_from_settings() # threads = [] for spider in spiders: # thread = threading.Thread(target=self._execute_one_spider_task, args=(spider,)) # threads.append(thread) # thread.start() # for thread in threads: # thread.join() # self._execute_one_spider_task(spider) # 使用异步的方式调用 self.coroutine_pool.apply_async(self._execute_one_spider_task, args=(spider, )) # 守护线程 self.coroutine_pool.join() def _execute_one_spider_task(self, spider): # 处理一个爬虫任务 try: # 遍历爬虫对象的get_proxies方法,获取代理IP for proxy in spider.get_proxies(): # self.__dispose_one(proxy) self.coroutine_pool.apply_async(self.__dispose_one, args=(proxy, )) # 守护线程 self.coroutine_pool.join() except Exception as e: logger.exception(e) def __dispose_one(self, proxy): # 检测代理IP的可用性 proxy = check_proxy(proxy) # 如果可用,写入数据库 if proxy.speed != -1: # 可用,写入数据库 self.mongo_pool.insert_one(proxy) @classmethod def start(cls): rs = cls() rs.run()
class RunSpider(object): def __init__(self): # 创建mongo对象 self.mongo_pool = MongoPool() # 创建协程池对象 self.coroutine_pool = Pool() def get_spider_from_settings(self): """根据配置文件信息获取爬虫列表""" # 遍历配置文件中爬虫信息,获取每个爬虫全类名 for full_class_name in PROXIES_SPIDERS: # core.proxy_spider.proxy_spiders.xiciSpider # 获取模块名 和 类名 moudle_name, class_name = full_class_name.rsplit('.', maxsplit=1) # 根据模块名导入模块 moudle = importlib.import_module(moudle_name) # 根据类名从模块中获取类 clas = getattr(moudle, class_name) # 创建爬虫对象 spider = clas() yield spider def run(self): # 根据配置文件信息,获取爬虫对象列表 spiders = self.get_spider_from_settings() for spider in spiders: # 使用异步执行这个方法 # self.__execute_one_spider_task(spider) self.coroutine_pool.apply_async(self.__execute_one_spider_task, args=(spider, )) self.coroutine_pool.join() def __execute_one_spider_task(self, spider): # 把处理一个代理爬虫的代码抽到一个方法 """用于处理一个爬虫任务""" try: # 遍历爬虫对象get_proxies()方法,获取代理IP for proxy in spider.get_proxies(): # print(proxy) # 检测代理IP是否可用(代理IP检测模块) proxy = check_proxt(proxy) # 如果可用,写入数据库(数据库模块) # 如果speed不为-1,就说明可用 if proxy.speed != -1: # 导入数据库(数据库模块) self.mongo_pool.insert_one(proxy) except Exception as e: logger.exception(e) @classmethod def start(cls): # - 定义一个start的类方法 # - 创建当前类的对象,调用run方法 rs = RunSpider() rs.run() # 使用schedule模块,每隔一定的时间,执行当前对象的run方法 schedule.every(RUN_SPIDERS_INTERVAL).hours.do(rs.run) while True: schedule.run_pending() time.sleep(1)
class RunSpider(object): def __init__(self): # 创建MongoPool对象 self.mongopool = MongoPool() # 3,使用异步来执行每一个爬虫任务 # 3.1 在init方法中创建协程池队象 self.coroutine_pool = Pool() def get_spider_from_settings(self): """根据配置文件信息,获取爬虫对象列表""" # 遍历配置文件中爬虫信息,获取每个爬虫全类名 for full_class_name in PROXIES_SPIDERS: # core.proxy_spider.proxy_spiders.XiLaSpider # 获取模块名和类名 # print(full_class_name.rsplit('.',maxsplit=1)) module_name, class_name = full_class_name.rsplit('.', maxsplit=1) # 根据模块名导入模块 module = importlib.import_module(module_name) # 根据类名从模块中获取类 cls = getattr(module, class_name) # 创建爬虫对象 spider = cls() # print(spider) # 也可以通过列表.append 然后返回列表 yield spider # 提供一个运行爬虫的run方法 def run(self): # 2.1 根据配置文件信息,获取爬虫对象列表 spiders = self.get_spider_from_settings() # 2.2 遍历对象列表,获取爬虫对象,遍历爬虫对象的get_proxies方法,获取ip for spider in spiders: # 3.3 使用异步执行此方法 # self.__excute_one_spider(spider) self.coroutine_pool.apply_async(self.__excute_one_spider, args=(spider, )) # 3.4 调用协程的join方法,让当前线程等待协程任务的完成 self.coroutine_pool.join() def __excute_one_spider(self, spider): # 3.2 在处理一个代理爬虫的代码抽到一个方法 # 用于处理一个爬虫任务 # 2.5 异常处理,防止一个爬虫出错影响其他的爬虫 try: # 遍历爬虫对象的get_proxies方法,获取ip for proxy in spider.get_proxies(): # print(proxy) # 2.3 检测代理ip proxy = check_proxy(proxy) # 2.4 如果可用,写入数据库 # 如果speed不为-1,说明可用 if proxy.speed != -1: # 写入数据库 self.mongopool.insert_one(proxy) except Exception as ex: logger.exception(ex) @classmethod def start(cls): # 4 使用schedule模块,实现每个一定的时间,执行一次爬虫任务 # 4.1 定义一个start的类方法 # 4.2 创建当前类的对象,调用run方法 rs = RunSpider() rs.run() # 4.3 使用schedule模块,每个一定时间,执行当前对象的run方法 # 4.3.1 修改配置文件,增加爬虫运行时间间隔的配置,单位为小时 schedule.every(RUN_SPIDER_INTERVAL).hours.do(rs.run) while True: schedule.run_pending() time.sleep(1)
area = self.get_first_ele(tr.xpath(self.detail_xpath['area'])) proxy = Proxy(ip, port, area=area) yield proxy def get_first_ele(self, lis): return lis[0] if len(lis) != 0 else '' def get_proxies(self): for url in self.urls: page = self.get_page_from_url(url) proxies = self.get_proxies_from_page(page) yield from proxies if __name__ == '__main__': config = { 'urls': ['https://www.xicidaili.com/nt/{}'.format(i) for i in range(1, 4)], 'group_xpath': '//*[@id="ip_list"]/tr', # 查看网页源代码里面是否真的有tbody, 'detail_xpath': { 'ip': './td[2]/text()', 'port': './td[3]/text()', 'area': './td[4]/a/text()', } } c_spider = BaseSpider(**config) for line, _ in enumerate(c_spider.get_proxies()): mongo = MongoPool() mongo.insert_one(_) print(line, _)
class RunSpider(object): def __init__(self): #创建MongoDB对象 self.mongo_pool = MongoPool() #在init中创建协程池 self.coroutine_pool = Pool() def get_spider_from_setting(self): """根据配置文件信息,获取爬虫对象列表""" #遍历配置文件中爬虫信息,获取每隔爬虫的全类名 for full_class_name in PROXIES_SPIDERS: #获取模块名和类名 module_name, class_name = full_class_name.rsplit('.', maxsplit=1) #根据模块名导入模块 module = importlib.import_module(module_name) #根据类名,从模块中获取类 cls = getattr(module, class_name) #创建爬虫对象 spider = cls() yield spider def run(self): #2.1根据配置文件信息,获取爬虫对象列表 spiders = self.get_spider_from_setting() for spider in spiders: #2.5处理异常,防止一个爬虫内部出错,影响其他的爬虫 #3.3 通过异步执行这个方法 self.coroutine_pool.apply_async(self.__execute_one_spider_tack, args=(spider, )) # 调用协程的join方法,让当前线程等待队列完成 self.coroutine_pool.join() def __execute_one_spider_tack(self, spider): #3.2 把处理一个代理爬虫的代码抽到一个方法 #用于处理一个爬虫任务 try: # 遍历爬虫对象的get_proxies方法,获取代理IP for proxy in spider.get_proxies(): # 监测代理IP proxy = check_proxy(proxy) # 2.4如果可用,写入数据库 # 如果spider不为-1,说明可用 if proxy.speed != -1: # 写入数据库 self.mongo_pool.insert_one(proxy) except Exception as ex: logger.exception(ex) @classmethod def start(cls): """ 使用schedule模块,实现每隔一定时间,执行一次爬取任务 定义一个start的类方法 创建当前类的对象,调用run方法 使用schedule模块,每隔一定的时间,执行当前对象的run方法 :return: """ rs = RunSpider() rs.run() schedule.every(RUN_SPIDERS_INTERVAL).hour.do(rs.run) while True: schedule.run_pending() time.sleep(1)
class RunSpider(object): def __init__(self): # 创建MongoPool对象 self.mongo_pool = MongoPool() # 3.1 在init方法中创建协程池对象 self.coroutine_pool = Pool() def get_spider_from_settings(self): """根据配置文件信息, 获取爬虫对象列表.""" # 遍历配置文件中爬虫信息, 获取每个爬虫全类名 for full_class_name in PROXIES_SPIDERS: # core.proxy_spider.proxy_spiders.Ip66Spider # 获取模块名 和 类名 module_name, class_name = full_class_name.rsplit('.', maxsplit=1) # 根据模块名, 导入模块 module = importlib.import_module(module_name) # 根据类名, 从模块中, 获取类 cls = getattr(module, class_name) # 创建爬虫对象 spider = cls() # print(spider) yield spider def run(self): # 2.1 根据配置文件信息, 获取爬虫对象列表. spiders = self.get_spider_from_settings() # 2.2 遍历爬虫对象列表, 获取爬虫对象, 遍历爬虫对象的get_proxies方法, 获取代理IP for spider in spiders: # 2.5 处理异常, 防止一个爬虫内部出错了, 影响其他的爬虫. # 3.3 使用异步执行这个方法 # self.__execute_one_spider_task(spider) self.coroutine_pool.apply_async(self.__execute_one_spider_task, args=(spider, )) # 3.4 调用协程的join方法, 让当前线程等待 协程 任务的完成. self.coroutine_pool.join() def __execute_one_spider_task(self, spider): # 3.2 把处理一个代理爬虫的代码抽到一个方法 # 用于处理一个爬虫任务的. try: # 遍历爬虫对象的get_proxies方法, 获取代理I for proxy in spider.get_proxies(): # print(proxy) # 2.3 检测代理IP(代理IP检测模块) proxy = check_proxy(proxy) # 2.4 如果可用,写入数据库(数据库模块) # 如果speed不为-1, 就说明可用 if proxy.speed != -1: # 写入数据库(数据库模块) self.mongo_pool.insert_one(proxy) except Exception as ex: logger.exception(ex) @classmethod def start(cls): # 4. 使用schedule模块, 实现每隔一定的时间, 执行一次爬取任务 # 4.1 定义一个start的类方法 # 4.2 创建当前类的对象, 调用run方法 rs = RunSpider() rs.run() # 4.3 使用schedule模块, 每隔一定的时间, 执行当前对象的run方法 # 4.3.1 修改配置文件, 增加爬虫运行时间间隔的配置, 单位为小时 schedule.every(RUN_SPIDERS_INTERVAL).hours.do(rs.run) while True: schedule.run_pending() time.sleep(1)