scrapy爬虫框架深入理解 -- 未整理完
1. logging模块
2. 环境变量(setting)
2.1 如何设置并访问setting
2.1.1 在spider中
spider中,setting是一个继承scrapy.Spider的一个实例属性,可以通过self.setting访问对应在setting.py中的环境变量。
#在setting.py文件中
MONGO_URI=' 对应的URI'
#在spider中调用
class ExampleSpider(scrapy.Spider):
...#省略
def parse(self, response):
mongodb = self.settings['MONGO_URI']
logging.log(logging.INFO,mongodb)
#会在日志中输出
#2023-06-17 16:44:04 [root] INFO: 对应的URI
scrapy同样支持为每一个Spider设置不同的环境变量,以避免所有环境变量都挤在一个setting.py文件中造成臃肿。在每一个spider实例中都有一个继承来的custom_settings属性可以修改,它是一个字典类型,所有单独的环境变量都可以在这里声明,包括cookies, header, 以及其他可以写在setting.py文件中的变量。声明方法跟Spider的name属性相同。调用则通过self.custom_settings使用在方法中。
2.1.2 在pipeline等其他组件中
使用类方法from_crawler()可以访问到
官方文档参考
“Settings can be accessed through the scrapy.crawler.Crawler.settings attribute of the Crawler that is passed to from_crawler method in extensions, middlewares and item pipelines”
示例代码:
class MyExtension:
def __init__(self, log_is_enabled=False):
if log_is_enabled:
print("log is enabled!")
@classmethod
def from_crawler(cls, crawler):
settings = crawler.settings
return cls(settings.getbool("LOG_ENABLED"))
在from_crawler()
方法中的setting对象是一个类字典对象,因此可以用字典的方式访问环境变量(例如:e.g., settings['LOG_ENABLED']
),但是为了避免可能的类型错误(比如调用需要int类型,但是环境变量中是str类型,直接使用key访问就可能返回int类型造成错误),更推荐使用setting对象的api。
官方文档中setting对象的api
包括get()
,getbool()
,getdict()
,getdictorlist()
,getfloat()
,getint()
,getlist()
等,用途也能从方法名显而易见出,具体请参考官方链接。
1. crawler模块
2. item源码如何实现存储key字段,
https://www.cnblogs.com/twelfthing/articles/4709287.html
https://www.cnblogs.com/fengf233/p/11298623.html#2.field()%E7%B1%BB
5. 多个Spider以及多个Pipeline对应的设置
https://www.ziji.work/python/scrapy-many-spider-pipeline.html#SCRAPYSPIDER-4
6. 大佬的源码解析
虽然现在基本看不懂(×
http://kaito-kidd.com/2016/11/09/scrapy-code-analyze-entrance/
7. 访问setting
8. 为什么from_crawler方法需要设置为类方法?
提点链接
最后这篇博客的最后一句话简直一下子给我点透了,虽然之前专门去查了@classmethod
、factory method这些东西,但为什么这么做还是很混乱。
大概就是检测spider类有没有from_crawler,有的话就return一个cls()的实例化对象,产生实例化对象后会自动调__init__方法。
结合官方文档的Crawler API、pipeline中from_crawler()方法、Spider中from_crawler()方法,以及大佬对scrapy源码的解析才有一种突然醒悟的感觉。
PS. 这里我一直犯了一个概念上的错误,我一直以为示例代码中
from_crawler(cls, cralwer)
的crawler是类的属性参数(我误认为是有点像构造方法中的参数,被我搞混了😣),是一个定义在当前类里面的一个继承过来的属性,因此花了很多时间去查这个crawler
在scrapy中的作用。但是实际上它只是一个函数的形参,它本身不带有任何意义(就像是定义函数的时候括号里的a,b,c,d等参数一样)。然后又因为crawler在scrapy又是一个关键对象,所以查了很久都没有结果。
直到我看到了上面那篇提点链接的博客,这才想通了。
从我的理解来说 :
第一步,在运行这个爬虫之前,scrapy会为运行做一些准备,其中就包括判断pipeline, spider, 还有其他一些组件中的from_crawler()
方法是否被重写,这个判断就需要在类没有实例化之前调用,所以from_crawler()
被定义为类方法。
第二步,之后根据具体的类,在从Crawler这个对象中实例化一个对应的from_crawler方法。
上面这句话有两点需要着重理解。
- 第一点,这也就是
from_crawler()
是一个“factory method”,scrapy会根据不同的对象为类赋予不同的from_crawler()
方法。在我的理解中,就是有一个类,专门负责为其他不同的类赋予不同的from_crawler()
方法,也就是类方法的类。 - 第二点,scrapy从Crawler
创建from_crawler()
的含义就是为这个方法传入一个scrapy.crawler.Crawler
对象,而这个对象又是由scrapy通过一个Spider子类
和scrapy.settings.Settings
对象实例化而来。
官方文档
classscrapy.crawler.Crawler(spidercls, settings)
The Crawler object must be instantiated with a scrapy.Spider subclass and a scrapy.settings.Settings object.
因此,在Crawler对象中就有能过获取setting的API,这个API和2.1.2中的setting对象的一模一样(因为本来就是一个东西👏,都是setting对象,这里就有串起来的感觉了)
9. 设置cookies
知乎参考但是没有讲原理
10. 关闭scrapy日志
添加twisted定时器 以及 输出调用日志
https://www.jianshu.com/p/5a5cdd7f2bfb
11. 定时调度scrapy
https://blog.csdn.net/python36/article/details/82683528