scrapy使用yield返回Request的步骤是怎么样的
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了scrapy使用yield返回Request的步骤是怎么样的相关的知识,希望对你有一定的参考价值。
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。
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会帮你处理内部细节,你只管用就行了。
scrapy中Request中常用参数
url: 就是需要请求,并进行下一步处理的url callback: 指定该请求返回的Response,由那个函数来处理。 method: 一般不需要指定,使用默认GET方法请求即可 headers: 请求时,包含的头文件。一般不需要。内容一般如下:使用 urllib2 自己写过爬虫的肯定知道 Host: media.readthedocs.org User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0 Accept: text/css,*/*;q=0.1 Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Referer: http://scrapy-chs.readthedocs.org/zh_CN/0.24/ Cookie: _ga=GA1.2.1612165614.1415584110; Connection: keep-alive If-Modified-Since: Mon, 25 Aug 2014 21:59:35 GMT Cache-Control: max-age=0 meta: 比较常用,在不同的请求之间传递数据使用的。字典dict型 request_with_cookies = Request(url="http://www.example.com", cookies={‘currency‘: ‘USD‘, ‘country‘: ‘UY‘}, meta={‘dont_merge_cookies‘: True}) encoding: 使用默认的 ‘utf-8‘ 就行。 dont_filter: indicates that this request should not be filtered by the scheduler. This is used when you want to perform an identical request multiple times, to ignore the duplicates filter. Use it with care, or you will get into crawling loops. Default to False. errback: 指定错误处理函数
以上是关于scrapy使用yield返回Request的步骤是怎么样的的主要内容,如果未能解决你的问题,请参考以下文章
scrapy爬虫 用yield Request(response,循环获取网页出错
Scrapy(爬虫框架)中,Spider类中parse()方法的工作机制