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

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

猫烠⑼条掵仅有一顆心 发布于 2021-11-28 字数 331 浏览 893 回复 9

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

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

爱的故事 2021-12-01 9 楼

我这里不明白具体的程序执行步骤,所以在用scrapy写程序的时候无从下笔,在程序执行到yield Request()后,parse方法挂起,这时scrapy是调用了next函数去继续执行yield的后续部分,还是得到request对象后,scrapy调用downloader去下载网页,得到response,然后再调用parse方法,这不又重新开始了吗,这两条路那条才对,有点迷糊。

沙与沫 2021-12-01 8 楼

厉害

残花月 2021-12-01 7 楼

不用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会帮你处理内部细节,你只管用就行了。

终止放荡 2021-12-01 6 楼

我这里不明白具体的程序执行步骤,所以在用scrapy写程序的时候无从下笔,在程序执行到yield Request()后,parse方法挂起,这时scrapy是调用了next函数去继续执行yield的后续部分,还是得到request对象后,scrapy调用downloader去下载网页,得到response,然后再调用parse方法,这不又重新开始了吗,这两条路那条才对。

回眸一笑 2021-12-01 5 楼

回复
你这想法是错的。parse方法是个生成器,可迭代,不是一个操作流程。它里面的yield都是返回“独立”一个生成器,通过自身self.parse返回的,当最外层的parse迭代时候,里面的子生成器会被每次推送出来。整个parse就是产生一大堆相关的生成器。

冷默言语 2021-12-01 4 楼

回复
你别用过程方法去理解就行了,这个parse一大捆等着执行迭代的生成器组合。

丢了幸福的猪 2021-12-01 3 楼

回复
yield挂起返回的不止是值,也可以是生成器的。request那里就是一层层挖,把最底层的生成器拉出来。

草莓味的萝莉 2021-12-01 2 楼

回复
看来我对于yield的理解还是太浅了,对于yield我的理解就是每调用一次next(),函数就从yield出再次执行,可是把这一想法套到上面的例子就发现完全理解不了执行过程,你说的一层层的挖是什么意思,yield还可以进行递归?我理解的递归不就是调用自身吗

瀞厅☆埖开 2021-12-01 1 楼

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

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