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

 我来答
无语至极也
2017-06-15 · TA获得超过368个赞
知道小有建树答主
回答量:94
采纳率:100%
帮助的人:48万
展开全部

Python的yield是一个比较特别的关键字。

>>> def test_yield():
...     for i in range(3):
...         yield i
...
>>> test_yield()
<generator object test_yield at 0x01AB2C88>

很明显的看到,yield不同于return。return直接返回函数返回值。而包含yield的函数,不返回而是生成了一个对象。这个对象叫做生成器(generator)。实际上test_yield中的for循环并没有在调用test_yield函数时执行完毕,而是每次遇到yield都会停止在执行yield前,当你调用生成器的next方法时,yield就会执行,这时返回紧接着yield的变量。

>>> gen = test_yield()
>>> gen.next()
0
>>> gen.next()
1
>>> gen.next()
2
>>> gen.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

可以看到,返回2时,生成器中的for循环已经执行完毕,函数中没有可执行的yield。这时再next就会抛出StopIteration的异常,以此表示生成器的结束。

实际上,生成器也可用循环进行迭代。

>>> for each in test_yield():
...     print each
...
0
1
2

而且Python中xrange不同于range产生list,xrange产生的是一个生成器。

>>> range(3)
[0, 1, 2]
>>> xrange(3)
xrange(3)

在Scrapy中,Spider解析网页的方法中就用到yield。当然,不用yield也是可以的,但你需要返回一个包含从传入的Response中解析出的所有Request或是Item的list。

class DemoSpider(Spider):
    name = 'demo'
    ...
    def parse(self, response):
        sel = Selector(response)
        for url in sel.xpath('//a/@href').extract():
            yield Request(url)

或者

class DemoSpider(Spider):
    name = 'demo'
    ...
    def parse(self, response):
        sel = Selector(response)
        requests = []
        for url in sel.xpath('//a/@href').extract():
            requests.append(Request(url))
        return requests

总之,要返回一个可迭代的对象。

那么,为何要存在yield这种东西?直接返回list不成吗?试想一下,如果需要返回包含成百上千个元素的list,想必会占用很多计算机资源以及时间。如果用yield就可以缓和这种情况了。


以上部分代码仅适用Python2。

就烦条0o
2018-07-28 · 知道合伙人软件行家
就烦条0o
知道合伙人软件行家
采纳数:33315 获赞数:46492
从事多年系统运维,喜欢编写各种小程序和脚本。

向TA提问 私信TA
展开全部
不用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会帮你处理内部细节,你只管用就行了。
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式