看了 scrapy 官方说明文档,遇到几个问题恳请大家指点

2017-09-21 19:30:19 +08:00
 saximi

看了 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()方法不会被执行?如果是这样,什么情况下会如此? 

其次,既然是按照顺序依序调用中间件,那为什么要强调靠近引擎和靠近下载器?这个说法有什么特殊意义么? 

2564 次点击
所在节点    Python
6 条回复
mrzys
2017-09-21 19:55:20 +08:00
回答 1,使用 yield 的时候就是一个迭代器,可以不断 yield 新的 request,但是你用 return,就只会返回一个 request。
mrzys
2017-09-21 20:04:12 +08:00
这里的 yield 的值可以是 request 也可以是一个 item,如果是一个 item 就会调用 pipeline,如果设置的话。这里应该是为了降低内存的使用率所以直接返回一个列表。另外不知道是不是使用协程来控制对 parse 方法的调用。
PythonAnswer
2017-09-21 21:44:22 +08:00
x. 可以用最新版的 scrapy

x. parse 方法是设计好的,不要写个重名函数覆盖了。如果想重载,可以自己实现 parse 并加上想要的功能,但这不符合 scrapy 思想

x. 中间件顺序,请参考 scrapy 架构图,那张十字排列的 png
sunwei0325
2017-09-21 21:50:24 +08:00
现在都 1.4 了吧, 怎么还看这么古老版本的文档呢
saximi
2017-09-21 22:32:36 +08:00
@PythonAnswer 我用的 scrapy 是最新的,但是看的文档是 http://scrapy-chs.readthedocs.io/zh_CN/latest/ 这个网址的 0.25 中文版本,因为英文不好,所以只好看中文版本。
那张 png 的图我看了,我知道中间件是按照右侧带的序号作为顺序来执行的,但是我不知道反正都是下载器中间件,为何要强调靠近引擎还是靠近下载器,这毕竟和执行顺序无关,做这个强调有什么意义么?
PythonAnswer
2017-09-21 23:21:02 +08:00
中间件是有顺序的,middleware 这个概念,你可以参考下 django 里面的 middleware,摆放都是有顺序的。

比如做一碗阳春面。你抓来的数据只是面条,然后想煮成面。

1. 碗里放盐和味精
2. 放面条和汤
3. 搅拌
4. 撒上葱花点缀

中间件的顺序可不能乱了,不然面条就不好看。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/392636

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX