这是一篇没有什么重点的自我救赎文…
最近开始对框架进行下手了…
第一个框架就是比较熟悉的scrapy
框架,首先导入源码…
密密麻麻麻麻,好多文件,该怎么解析?该按着什么顺序去看所有的代码比较容易贯通呢?
scrapy
的大佬们,你们是怎么规划的呀,萌新求教啊T_T
内事不决问百度!搞他!
看了半天,感觉一看起框架就比较深奥了,大佬们的功力还是深厚…
我还是做一个适合我自己的攻略吧
先搞个项目:*家租房信息.搞他
首先访问主页,获取全国城市列表,拼接完整的url,访问各地租房的列表页.接着进行二次请求的发起,获取详情页的信息.
手软一点吧,就拿第一个城市的第一页列表页的详情页吧.
代码就不放了,能看这个的应该有点代码基础了吧…(自我YY)
写一下具体流程吧:
重写start_request()方法.
接下来我们来分析一下这个start_request()方法的作用(百度)
有一个感觉有点我想要的东西的链接:https://blog.csdn.net/qq_40605167/article/details/81387501
这里从start_urls开始请求,调用默认调用requests()方法.
[总结]:首先,start_urls
是存放开始请求的url,框架默认会调用start_requests()
方法,默认发送get请求
所以第一个问题,我在源码中看出它是从start_urls
中获取url,并且使用start_requests()
方法的?
- 去engine之类的文件中看一下吧.这么多文件怎么办?我从Windows.文件搜索…有点low,但是有用.
....scrapy/core/engine.py
找到一个py文件先看看吧
映入眼帘:自己要区分engine
和Scheduler
引擎和调度器.虽然在功能上不好区分,但是的确需要区分.
For more information see docs/topics/architecture.rst
了解更多的文件
接下来在代码中找信息吧
初始化中有self.start_requests= iter(start_requests)
先从简单的开始吧
iter(object[, sentinel])
:-
object – 支持迭代的集合对象
-
sentinel – 如果传递了第二个参数,则参数object必须是一个可调用的对象(如,函数),此时,iter创建了一个迭代器对象,每次调用这个迭代器对象的__next__()方法时,都会调用object.(Ps:现在好像更多的使用next()方法)
因此,这个初始化的代码就是将
start_requests
函数转成一个迭代器对象吗?
这时,我发现了一个更为基础的代码:初始化logger=logging.getLogger(__name__)
点进logging
看看.
看进去就是比较基础的配置了.
一些介绍,估计我这里还用不到,就先跳过,捡一些和我这次相关的看吧,不然真的太多了.(这让我压力很 大)
日志加载的一些配置,异常抛出的配置,再往下是一些参数的声明,**那些数字是端口号?应该不是吧,那那些数是做什么的?**突然想到了异常编号?应该是这个了吧。像下面这种语法是什么意思?
asctime_search = '${asctime}'
logging.py
就先到这里吧
回到engine.py
,这个生成器对象应该是以生成器的方式返回每次请求的结果.
然后并没有什么结论…
-
- 接下来继续找
start_requests()
函数相关的内容.
这次去找爬虫相关的文件…
在crawl.py
文件中的88行有一个start_requests()
,继续找,来到spider.py
的__init__.py
文件中,58行往下:
会发现最后面的for
循环,前面的判断是保证有请求的内容.因此,start_requests()
就是取出url发起请求的默认方式?这难免有点说服不了.但是这个类的声明中说所有的spider都必须是继承自这个类.因此…就可以了?深究下去我觉得我现在的能力也达不到了…虽然也难以说服自己.这个问题有待完善
接下来就是关于重写方法之后的问题了.
按照流程,当请求之后,默认返回给parse()
函数,那么如果我们在start_requests()
中指定了回调函数,而回调函数使用了父类的start_requests()
方法,那么,此时父类的start_requests()
方法还是原来的父类的方法吗?答案是肯定的,因为我们重写的是子类的start_requests()
方法而不是修改的父类的start_requests()
方法.
好了,到这里我的问题就解决了.我总是感觉我们重写了子类方法之后,回调父类方法是不是有些问题…现在梳理了一遍,没有什么问题了.
基础还是得巩固啊~都不好意思发了…