- import scrapy
- from text_info.items import TextInfoItem
- class A50zwSpider(scrapy.Spider):
- name = '50zw'
- allowed_domains = ['m.50zw.la']
- start_urls = ['http://m.50zw.la/wapsort/1_1.html']
- #主站链接 用来拼接
- base_site = 'http://m.50zw.la'
- def parse(self, response):
- book_urls = response.xpath('//table[@class="list-item"]//a/@href').extract()
- for book_url in book_urls:
- url = self.base_site + book_url
- yield scrapy.Request(url, callback=self.getInfo)
- #获取下一页
- next_page_url = self.base_site + response.xpath('//table[@class="page-book"]//a[contains(text()," 下一页 ")]/@href').extract()[0]
- yield scrapy.Request(next_page_url, callback=self.parse)
- def getInfo(self, response):
- item = TextInfoItem()
- #提取信息
- item['text_id'] = response.url.split('_')[1].replace('/', '')
- item['text_name'] = response.xpath('//table[1]//p/strong/text()').extract()[0]
- item['text_author'] = response.xpath('//table[1]//p/a/text()').extract()[0]
- item['text_type'] = response.xpath('//table[1]//p/a/text()').extract()[1]
- item['text_status'] = response.xpath('//table[1]//p/text()').extract()[2][3:]
- item['text_latest'] = response.xpath('//table[1]//p[5]/text()').extract()[0][3:]
- item['text_intro'] = response.xpath('//div[@class="intro"]/text()').extract()[0]
- yield item
spider 示例 (含 yield)
scrapy 错误: yield scrapy.Request() 不执行, 失效, Filtered offsite request to 错误. 首先我们在 Request() 方法里面添加这么一个东东:
yield Request(url, callback=self.parse_item, dont_filter=True)
如果发现成功执行, 那你就得检查一下你的: allowed_domains, 看看前面是不是添加了: http:// , 如 (错误写法):
allowed_domains = ["http://www.baidu.com"]
正确写法:
allowed_domains = ["www.baidu.com"]
去掉之后, 把 dont_filter=True 也去掉, 也能正常执行, 其实这里是 allowed_domains 和去重出现了冲突, scrapy allowed_domains 判断不严谨产生的问题, 所以书写 allowed_domains 的时候一定不要加: http://
其次 yield 必须出现在 response 的方法内部 即必须成对使用
- def parse_link_street(self, response):
- yield scrapy.Request(
- url=''' meta='',
- callback='',
- dont_filter=True
- )
- 而不能出现如下情况
- def parse_link_street(self):
- yield scrapy.Request(
- url=''' meta='',
- callback='',
- dont_filter=True
- )
参考: https://blog.csdn.net/weixin_40976261/article/details/88626108
yield 无效的情况
一,
这里我们通过 yield 来发起一个请求, 并通过 callback 参数为这个请求添加回调函数, 在请求完成之后会将响应作为参数传递给回调函数.
scrapy 框架会根据 yield 返回的实例类型来执行不同的操作, 如果是 scrapy.Request 对象, scrapy 框架会去获得该对象指向的链接并在请求完成后调用该对象的回调函数.
如果是 scrapy.Item 对象, scrapy 框架会将这个对象传递给 pipelines.py 做进一步处理.
这里我们有三个地方使用了 yield , 第一个地方是:
- for book_url in book_urls:
- url = self.base_site + book_url
- yield scrapy.Request(url, callback=self.getInfo)
二,
- #获取下一页
- next_page_url = self.base_site + response.xpath('//table[@class="page-book"]//a[contains(text()," 下一页 ")]/@href').extract()[0]
- yield scrapy.Request(next_page_url, callback=self.parse)
这里是在爬取完一页的信息后, 我们在当前页面获取到了下一页的链接, 然后通过 yield 发起请求, 并且将 parse 自己作为回调函数来处理下一页的响应.
这有点像递归, 不过递归是函数自己调用自己, 这里看起来好像是 parse 调用了自己, 但实际上 parse 是由 scrapy 框架在获得响应后调用的.
三,
- def getInfo(self, response):
- item = TextInfoItem()
- ... ...
- item['text_intro'] = response.xpath('//div[@class="intro"]/text()').extract()[0]
- yield item
这里我们通过 yield 返回的不是 Request 对象, 而是一个 TextInfoItem 对象.
scrap 有框架获得这个对象之后, 会将这个对象传递给 pipelines.py 来做进一步处理.
我们将在 pipelines.py 里将传递过来的 scrapy.Item 对象保存到数据库里去.
来源: http://www.bubuko.com/infodetail-3460428.html