爬虫进阶:框架功能完善-江南app体育官方入口
动态导入模块
目前代码存在的问题
通过前面的代码编写,我们已经能够完成大部分的任务,但是在main.py
中的代码非常臃肿,对应的我们可以再settings.py
配置哪些爬虫,管道,中间件需要开启,能够让整个代码的逻辑更加清晰
模块动态导入的方法
- 利用
importlib.import_modle
能够传入模块的路径,即可即可实现根据模块的位置的字符串,导入该模块的功能 - 在项目路径下新建
test.py
观察现象,插入如下代码观察现象
在settings中设置spider,middlewares
利用在配置文件中设置需要启用的爬虫类、管道类、中间件类
利用importlib模块,在引擎中动态导入并实例化
....
from scrapy_plus.conf.settings import spiders, pipelines, \
spider_middlewares,downloader_middlewares
class engine:
'''完成对引擎模块的封装'''
def __init__(self):
'''
实例化其他的组件,在引起中能够通过调用组件的方法实现功能
'''
self.spiders = self._auto_import_instances(spiders,isspider=true)
self.downloader = downloader()
self.scheduler = scheduler()
self.pipelines = self._auto_import_instances(pipelines)
self.spider_mids = self._auto_import_instances(spider_middlewares)
self.downloader_mids =self._auto_import_instances(downloader_middlewares)
self.total_request_nums = 0
self.total_response_nums = 0
def _auto_import_instances(self,path=[],isspider=false):
'''通过配置文件,动态导入类并实例化
path: 表示配置文件中配置的导入类的路径
isspider: 由于爬虫需要返回的是一个字典,因此对其做对应的判断和处理
'''
# 该方法不仅实例化动态导入爬虫,还有管道和中间件,而前者返回应是字典类型
if isspider is true:
instances = {}
else:
instances = [] # 存储对应类的实例对象
for p in path:
module_name = p.rsplit(".",1)[0] # 取出模块名称
cls_name = p.rsplit(".",1)[1] # 取出类名称
ret = importlib.import_module(module_name) # 动态导入爬虫模块
cls = getattr(ret, cls_name) # 根据类名称获取类对象
if isspider is true:
instances[cls.name] = cls()
else:
instances.append(cls()) # 实例化类对象
return instances # 返回类对象
......
修改main.py
这样main.py就不用再导入并传入那么多对象了:
# project_dir/main.py
from scrapy_plus.core.engine import engine # 导入引擎
if __name__ == '__main__':
engine = engine() # 创建引擎对象
engine.start() # 启动引擎