scrapy 下面为啥return 和yield 都能操作

最近在搞分布式,但是爬的时候 yield 和return 都能返回数据,这是为啥?
求人指教

tags.append(tag['name'])

item['tags'] = ','.join(tags)
item['fullName'] = companyData['fullName']
item['scale'] = companyData['scale']
asTs, asEncryptedTs = execjs.compile(self.js_read).call('p')
kw_url = 'https://rong.36kr.com/n/api/search/company?asEncryptedTs={}&asTs={}&kw={}&sortField=MATCH_RATE'.format(
    asEncryptedTs, asTs, item['name'])

retunr scrapy.Request(
    url=kw_url,
    callback=self.get_kw_info,
    dont_filter=True,
    meta={'id': response.meta['id'], 'item': item},
)

def get_kw_info(self, response):

item = response.meta['item']
pageData = json.loads(response.text)['data']['pageData']['data']
industryStr = pageData[0]['industryStr']
item['industryStr'] = industryStr
asTs, asEncryptedTs = execjs.compile(self.js_read).call('p')
finance_link = "https://rong.36kr.com/n/api/company/{}/finance?asEncryptedTs={}&asTs={}".format(
    response.meta['id'], asEncryptedTs, asTs)
retun scrapy.Request(
    url=finance_link,
    callback=self.get_finance_info,
    dont_filter=True,
    meta={'id': response.meta['id'], 'item': item})

这段代码总是我yield 和return 都能返回数据?这是为啥?

阅读 5.1k
1 个回答

这个问题其实是yieldreturn有什么不同的区别,return不必多讲,肯定明白。所以这个问题变成了yield是什么。

在进入正文之前可能需要明白是什么是生成器,在生成器之前,你需要明白的是什么是迭代。

迭代

假如一个列表,他就是可迭代对象,在Python里面叫做Iterable。

In [1]: _list = [1, 2, 3]

In [2]: for i in _list:
   ...:     print(i)
   ...:
1
2
3

可迭代对象如果觉得比较抽象,可以打比方讲,可迭代的就是“一排东西”。比如列表,字符串等等。

生成器

生成器当然也是可以迭代的,但是只能读取一次,因为它的值并不存在与内存中(实时生成)。

In [5]: _generator = (x**x for x in range(1, 4))

In [6]: for i in _generator:
   ...:     print(i)
   ...:
1
4
27

In [7]: for i in _generator:
   ...:     print(i)
   ...:

yield

yield是与return类似的作用,但yield只返回的是一个生成器。但是在Scrapy中对一个列表进行抓取经常会用到for循环。当然了下面的只是一个例子。

In [10]: def foo():
    ...:     _list = range(4)
    ...:     for i in _list:
    ...:         yield i
    ...:

In [11]: gen = foo()

In [12]: gen
Out[12]: <generator object foo at 0x00000130A6969C50>

In [13]: for i in gen:
    ...:     print(i)
    ...:
0
1
2
3

In [14]: for i in gen:
    ...:     print(i)
    ...:

你只需要明白在在调用foo的时候,函数内部不会立即执行,只是返回了一个生成器对象。在迭代的时候函数会开始执行,当在yield的时候,会返回当前值(i)。之后的这个函数会在循环中进行,直到没有下一个值。

In [15]: def foo():
    ...:     _list = range(4)
    ...:     print('run in func')
    ...:     for i in _list:
    ...:         print('run in loop')
    ...:         yield i
    ...:
    ...:

In [16]: gen = foo()

In [17]: for i in gen:
    ...:     print(i)
    ...:
    ...:
run in func
run in loop
0
run in loop
1
run in loop
2
run in loop
3

所以了~你应该明白Scrapy中的return与yield的区别了吧~

推荐问题