scrapy使用yield返回Request的步骤(应该是最清楚的)

人盡茶涼 提交于 2020-02-07 04:18:27

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

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

1

2

3

4

5

6

>>> def test_yield():

...     for 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的变量。

1

2

3

4

5

6

7

8

9

10

11

>>> gen = test_yield()

>>> gen.next()

0

>>> gen.next()

1

>>> gen.next()

2

>>> gen.next()

Traceback (most recent call last):

  File "<stdin>", line 1in <module>

StopIteration

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

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

1

2

3

4

5

6

>>> for each in test_yield():

...     print(each)

...

0

1

2

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

1

2

3

4

>>> range(3)

[012]

>>> xrange(3)

xrange(3)

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

1

2

3

4

5

6

7

class DemoSpider(Spider):

    name = 'demo'

    ...

    def parse(self, response):

        sel = Selector(response)

        for url in sel.xpath('//a/@href').extract():

            yield Request(url)

或者

1

2

3

4

5

6

7

8

9

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就可以缓和这种情况了。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!