【问题标题】:multiple requests to make an item in scrapy在scrapy中制作项目的多个请求
【发布时间】:2023-04-06 05:40:01
【问题描述】:

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

我必须发出 3 个获取请求才能生成 Product 项目。

  1. product_url
  2. category_url
  3. stock_url

首先,我需要对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 的情况下是否可行?

【问题讨论】:

  • 每张票你应该只问一个问题!如果每个问题有 2 个单独的答案,哪一个会被接受?
  • @Andersson 哎呀,注意到了。
  • 看起来您在编辑中删除了这两个问题。
  • 第一次请求进入产品后是不是无法获取品类和库存信息
  • @stranac 已修复!

标签: python web-scraping scrapy


【解决方案1】:

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

您可以使用(未​​记录的)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

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

【讨论】:

  • 所有股票信息都在一个页面中,所以这是完美的。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-20
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多