看了 scrapy 0.25 官方说明文档,遇到几个问题,烦请大家指点,感谢!
1、对于下面的 parse_item 方法,请问为什么要用 yield 返回,把 yield 删除,直接执行 scrapy.Request 会有何问题呢,或者是用 return 来返回 Request()又如何呢?
def parse_item(self, response):
item = MyItem()
yield scrapy.Request(item_details_url, self.parse_details, meta={'item': item})
2、文档在描述“ CrawlSpider ”用法时警告到:
“当编写爬虫规则时,请避免使用 parse 作为回调函数。 由于 CrawlSpider 使用 parse 方法来实现其逻辑,如果 您覆盖了 parse 方法,crawl spider 将会运行失败。”
但是我看到有的爬虫程序中,参数用的是 CrawlSpider,并且自己重写了 parse 函数,在 parse 函数中用 yield 返回 Request 时,把 parse_item 作为回调函数,也是可以运行的。
这是否说明上面的警告其实是不正确的?
3、在描述“ CrawlSpider ”用法时还解释了对如下爬取规则的用法:
class scrapy.contrib.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)
文档提到:“ follow 是一个布尔(boolean)值,指定了根据该规则从 response 提取的链接是否需要跟进。 如果 callback 为 None,follow 默认设置为 True,否则默认为 False。”
我的问题是,如果 callback 为 None,这个时候对于链接要跟进,请问跟进是什么意思? 既然没有回调函数,那要如何处理当前页面呢?
4、关于下载器中间件,文档提到:“ DOWNLOADER_MIDDLEWARES 字典里的中间件会根据顺序(order)进行排序,最后得到启用中间件的有序列表: 第一个中间件是最靠近引擎的,最后一个中间件是最靠近下载器的”
我的问题如下:
首先,是否所有在字典里的中间件都一定会被调用,有没有可能只调用其中排在前面的某几个,而其余中间件的 process_request()方法不会被执行?如果是这样,什么情况下会如此?
其次,既然是按照顺序依序调用中间件,那为什么要强调靠近引擎和靠近下载器?这个说法有什么特殊意义么?
1
mrzys 2017-09-21 19:55:20 +08:00 via Android
回答 1,使用 yield 的时候就是一个迭代器,可以不断 yield 新的 request,但是你用 return,就只会返回一个 request。
|
2
mrzys 2017-09-21 20:04:12 +08:00 via Android
这里的 yield 的值可以是 request 也可以是一个 item,如果是一个 item 就会调用 pipeline,如果设置的话。这里应该是为了降低内存的使用率所以直接返回一个列表。另外不知道是不是使用协程来控制对 parse 方法的调用。
|
3
PythonAnswer 2017-09-21 21:44:22 +08:00 via Android
x. 可以用最新版的 scrapy
x. parse 方法是设计好的,不要写个重名函数覆盖了。如果想重载,可以自己实现 parse 并加上想要的功能,但这不符合 scrapy 思想 x. 中间件顺序,请参考 scrapy 架构图,那张十字排列的 png |
4
sunwei0325 2017-09-21 21:50:24 +08:00
现在都 1.4 了吧, 怎么还看这么古老版本的文档呢
|
5
saximi OP @PythonAnswer 我用的 scrapy 是最新的,但是看的文档是 http://scrapy-chs.readthedocs.io/zh_CN/latest/ 这个网址的 0.25 中文版本,因为英文不好,所以只好看中文版本。
那张 png 的图我看了,我知道中间件是按照右侧带的序号作为顺序来执行的,但是我不知道反正都是下载器中间件,为何要强调靠近引擎还是靠近下载器,这毕竟和执行顺序无关,做这个强调有什么意义么? |
6
PythonAnswer 2017-09-21 23:21:02 +08:00
中间件是有顺序的,middleware 这个概念,你可以参考下 django 里面的 middleware,摆放都是有顺序的。
比如做一碗阳春面。你抓来的数据只是面条,然后想煮成面。 1. 碗里放盐和味精 2. 放面条和汤 3. 搅拌 4. 撒上葱花点缀 中间件的顺序可不能乱了,不然面条就不好看。 |