首页 > 解决方案 > Scrapy:按顺序抓取网页并在自定义函数中生成抓取的数据

问题描述

我想使用 Scrapy 抓取市场网站以查找已售商品。我想一次做一个项目,因为,例如,如果我调用第 555566 号项目,但没有这样的项目,网页只会显示“不正确的项目”,我只能在响应通过后关闭蜘蛛. 到那时,Scrapy 将调用更多页面,而我不希望这样。

Scrapy首先在方法中爬取起始商品页面start_requests,然后在方法中调用api获取该特定商品的销售数据parse,然后在方法中提取数据parse_item。我想在一个单独的函数中产生这些数据,因为我需要在start_requests方法末尾使用下一个项目编号再次调用该parse_item方法。

这就是我正在努力解决的部分。

  1. 再打电话start_requests就不行了。

  2. 如果我注释掉函数中的yield命令yield_data,该项目就会很好地打印在控制台中。但是在yield未注释命令的情况下,程序似乎甚至没有进入该yield_data功能。这是为什么?

我很感激这方面的任何帮助。这是代码:

import scrapy
import json
from scrapy.exceptions import CloseSpider

class_itemsSpider(scrapy.Spider):
     name = 'items'

     id = 555555
     def start_requests(self):        
         url = 'https://market.com/item/' + str(self.id)
         index = self.id
         self.id += 1
         yield scrapy.Request(url, meta={'index':index})

     def parse(self, response):
         index = response.meta['index']
         if b'Incorrect' in response.body:
             raise CloseSpider('Incorrect item')
         url = 'https://market.com/api/item?ajax=1&itemid=' + str(index)
    
         request = scrapy.Request(url, callback=self.parse_item, 
             headers={
                 'accept': 'application/json, text/plain, */*',
                 'user-agent': 'Mozilla/5.0'
             })
         yield request

     def parse_item(self, response):
         raw_data = response.body
         data = json.loads(raw_data)
         item = {
                 'Name':data['name'],
                 'Price':data['price'],
             }

         self.yield_data(item)
         # call start_requests again
         self.start_requests()

     def yield_data(self,_item):
         self.logger.info('Printing_item')
         print(item)
         self.logger.info('Yielding_item')
         yield item

标签: pythonscrapy

解决方案


好的,我想通了。也许它会帮助某人。我想yield作为完成代码执行的东西,但你可以产生数据,然后产生一个带有回调parse方法的请求。

import scrapy
import json
from scrapy.exceptions import CloseSpider

class_itemsSpider(scrapy.Spider):
    name = 'items'
    id = 555555

    start_urls = ['https://market.com/item/' + str(id)]
    
    def parse(self, response):
        if b'Invalid' in response.body:
            raise CloseSpider('Invalid item')

        index = self.id
        self.id += 1
        
        url = 'https://market.com/api/item?ajax=1&itemid=' + str(index)
        
        request = scrapy.Request(url, callback=self.parse_item, 
            headers={
                'accept': 'application/json, text/plain, */*',
                'user-agent': 'Mozilla/5.0'}, 
                 meta={'index':index})
  
        yield request

    def parse_item(self, response):
        index = response.meta['index']
        raw_data = response.body
        data = json.loads(raw_data)
        yield {
            'Name':data['name'],
            'Price':data['price'],
             }

        url = 'https://market.com/item/' + str(self.id)
        yield scrapy.Request(url, callback=self.parse)

推荐阅读