在scrapy中制作项目的多个请求

时间:2018-04-19 08:37:56

标签: python web-scraping scrapy

我是scrapy的新手,我遇到了一个复杂的案例。

我必须提出3个get请求才能生成Product个项目。

  1. product_url
  2. category_url
  3. stock_url
  4. 首先,我需要product_url的请求和category_url的请求,以填写Product项的字段。然后我需要参考stock_url的回复来确定是保存还是丢弃创建的项目。

    这就是我现在正在做的事情:

    在我的蜘蛛中,

    def start_requests(self):
        product_url = 'https://www.someurl.com/product?'
    
        item = ProductItem()
        yield scrapy.Request(product_url, self.parse_products, meta={'item':item})
    
    def parse_products(self, response):
        # fill out 1/2 of fields of ProductItem
        item = response.meta['item']
        item[name] = response.xpath(...)
        item[id] = response.xpath(...)
    
        category_url = 'https://www.someurl.com/category?'
        yield scrapy.Request(category_url, self.parse_products2, meta={'item':item})
    
    def parse_products2(self, response):
        # fill out rest of fields of ProductItem
        item = response.meta['item']
        item[img_url] = response.xpath(...)
        item[link_url] = response.xpath(...)
    
        stock_url = 'https://www.someurl.com/stock?'
        yield scrapy.Request(stock_url, self.parse_final, meta={'item':item})
    
    def parse_final(self, response):
        item = response.meta['item']
    
        for each prod in response:
            if prod.id == item['id'] & !prod.in_stock:
                #drop item
    

    问题:我之前被告知要处理管道中的项目丢弃逻辑。但是我是否放弃一个项目取决于另一个GET请求。我是否仍应将此逻辑移至管道/这是否可以继承scrapy.Spider?

1 个答案:

答案 0 :(得分:0)

将项目删除逻辑移动到管道可能是最好的设计。

您可以使用(未​​记录的)scrapy引擎api在管道中下载请求。假设可以从单个URL访问所有项目的股票信息的示例:

import scrapy
from scrapy.exceptions import DropItem
from twisted.internet.defer import inlineCallbacks


class StockPipeline(object):
    @inlineCallbacks
    def open_spider(self, spider):
        req = scrapy.Request(stock_url)
        response = yield spider.crawler.engine.download(req, spider)
        # extract the stock info from the response
        self.stock_info = response.text

    def process_item(self, item, spider):
        # check if the item should be dropped
        if item['id'] not in self.stock_info:
            raise DropItem
        return item

如果股票信息有单独的每个项目网址,您只需在process_item()中进行下载。