scrapy使用yield返回Request的步骤是怎么样的

sunzhaoxing 发布于 2015/06/03 21:27
阅读 18K+
收藏 1

程序如图所示,是教程上的一个例子,我知道yield是一个迭代器,用next函数可以在上一次的挂起处继续运行,但是在在这里,我不明白for+yield语句的执行步骤是什么了,在scrapy中是如何使用next函数以实现Request对象递归使用的呢

加载中
0
雪梨苹果
雪梨苹果

def parse是个迭代器,拿来多次执行迭代输出的内容,里面的第一个for(yield)是抓取当前response中所有的h3实体,第二个for(yield)是抓取当前response的里面链接,再进行子request,不断执行parse,是个递归。

整个东西就是抓取所有链接的h3实体。


s
sunzhaoxing
回复 @雪梨苹果 : 看来我对于yield的理解还是太浅了,对于yield我的理解就是每调用一次next(),函数就从yield出再次执行,可是把这一想法套到上面的例子就发现完全理解不了执行过程,你说的一层层的挖是什么意思,yield还可以进行递归?我理解的递归不就是调用自身吗
雪梨苹果
雪梨苹果
回复 @sunzhaoxing : yield挂起返回的不止是值,也可以是生成器的。request那里就是一层层挖,把最底层的生成器拉出来。
雪梨苹果
雪梨苹果
回复 @sunzhaoxing : 你别用过程方法去理解就行了,这个parse一大捆等着执行迭代的生成器组合。
雪梨苹果
雪梨苹果
回复 @sunzhaoxing : 你这想法是错的。parse方法是个生成器,可迭代,不是一个操作流程。它里面的yield都是返回“独立”一个生成器,通过自身self.parse返回的,当最外层的parse迭代时候,里面的子生成器会被每次推送出来。整个parse就是产生一大堆相关的生成器。
s
sunzhaoxing
我这里不明白具体的程序执行步骤,所以在用scrapy写程序的时候无从下笔,在程序执行到yield Request()后,parse方法挂起,这时scrapy是调用了next函数去继续执行yield的后续部分,还是得到request对象后,scrapy调用downloader去下载网页,得到response,然后再调用parse方法,这不又重新开始了吗,这两条路那条才对。
0
万里谁能驯
万里谁能驯
不用yield写一次parse方法你就明白了:
def parse(self, response):
    result_list = []
    for h3 in response.xpath("//h3").extract():
        result_list.append(MyItem(title=h3)

    for url in response.xpath("//a/@href").extract():
        result_list.append(scrapy.Request(url, callback=self.parse))

    return result_list



区别在于用了yield的函数会返回一个生成器,生成器不会一次把所有值全部返回给你,而是你每调用一次next返回一个值。

如果你想了解生成器和迭代器,可以去看相关文档。

它们的用法很简单:

for item in list:
    process(item)

for item in iterator:
    process(item)

for item in generator:
    process(item)

Python会帮你处理内部细节,你只管用就行了。
swelltt
swelltt
厉害
s
sunzhaoxing
我这里不明白具体的程序执行步骤,所以在用scrapy写程序的时候无从下笔,在程序执行到yield Request()后,parse方法挂起,这时scrapy是调用了next函数去继续执行yield的后续部分,还是得到request对象后,scrapy调用downloader去下载网页,得到response,然后再调用parse方法,这不又重新开始了吗,这两条路那条才对,有点迷糊。
返回顶部
顶部