scrapy中 yield使用详解

 1 import scrapy
 2 from text_info.items import TextInfoItem
 3  
 4 class A50zwSpider(scrapy.Spider):
 5     name = '50zw'
 6     allowed_domains = ['m.50zw.la']
 7     start_urls = ['http://m.50zw.la/wapsort/1_1.html']
 8  
 9     #主站链接 用来拼接
10     base_site = 'http://m.50zw.la'
11  
12     def parse(self, response):
13         book_urls = response.xpath('//table[@class="list-item"]//a/@href').extract()
14  
15         for book_url in book_urls:
16             url = self.base_site + book_url
17             yield scrapy.Request(url, callback=self.getInfo)
18  
19         #获取下一页
20         next_page_url = self.base_site + response.xpath('//table[@class="page-book"]//a[contains(text(),"下一页")]/@href').extract()[0]
21         yield scrapy.Request(next_page_url, callback=self.parse)
22  
23     def getInfo(self, response):
24         item = TextInfoItem()
25  
26         #提取信息
27         item['text_id'] = response.url.split('_')[1].replace('/', '')
28         item['text_name'] = response.xpath('//table[1]//p/strong/text()').extract()[0]
29         item['text_author'] = response.xpath('//table[1]//p/a/text()').extract()[0]
30         item['text_type'] = response.xpath('//table[1]//p/a/text()').extract()[1]
31         item['text_status'] = response.xpath('//table[1]//p/text()').extract()[2][3:]
32         item['text_latest'] = response.xpath('//table[1]//p[5]/text()').extract()[0][3:]
33         item['text_intro'] = response.xpath('//div[@class="intro"]/text()').extract()[0]
34  
35         yield item

这里我们通过 yield 来发起一个请求,并通过 callback 参数为这个请求添加回调函数,在请求完成之后会将响应作为参数传递给回调函数。

scrapy框架会根据 yield 返回的实例类型来执行不同的操作,如果是 scrapy.Request 对象,scrapy框架会去获得该对象指向的链接并在请求完成后调用该对象的回调函数。

如果是 scrapy.Item 对象,scrapy框架会将这个对象传递给 pipelines.py做进一步处理。

这里我们有三个地方使用了 yield :

第一个地方是:

1 for book_url in book_urls:
2         url = self.base_site + book_url
3         yield scrapy.Request(url, callback=self.getInfo)

这里我们在循环里不断提取小说详细页面的链接,并通过 yield 来发起请求,并且还将函数 getInfo 作为回调函数来从响应中提取所需的数据。

第二个地方是: 

1 #获取下一页
2 next_page_url = self.base_site + response.xpath('//table[@class="page-book"]//a[contains(text(),"下一页")]/@href').extract()[0]
3 yield scrapy.Request(next_page_url, callback=self.parse)

这里是在爬取完一页的信息后,我们在当前页面获取到了下一页的链接,然后通过 yield 发起请求,并且将 parse 自己作为回调函数来处理下一页的响应。

这有点像递归,不过递归是函数自己调用自己,这里看起来好像是 parse 调用了自己,但实际上 parse 是由 scrapy框架在获得响应后调用的。

最后一处使用了 yield 的地方在 getInfo 函数里:

1 def getInfo(self, response):
2         item = TextInfoItem()
3         
4         ... ...
5         
6         item['text_intro'] = response.xpath('//div[@class="intro"]/text()').extract()[0]
7         yield item

这里我们通过 yield 返回的不是 Request 对象,而是一个 TextInfoItem 对象。

scrap有框架获得这个对象之后,会将这个对象传递给 pipelines.py来做进一步处理。

我们将在 pipelines.py里将传递过来的 scrapy.Item 对象保存到数据库里去。

posted @ 2020-12-25 09:27  超级爱度假  阅读(744)  评论(0)    收藏  举报