Scrapy объединяет связанные запросы в один - PullRequest
0 голосов
/ 11 июня 2018

У меня есть сценарий, когда я просматриваю магазин, просматривая десятки страниц.Затем, когда я найду нужный товар, я добавлю его в корзину.

Наконец, я хочу оформить заказ.Проблема заключается в том, что при использовании цепочки скрапа требуется извлекать корзину столько раз, сколько у меня есть элементов в корзине.

Как объединить связанные запросы в один, поэтому после добавления 10 элементов вкорзина, оформление заказа вызывается только один раз?

def start_requests(self):
    params = getShopList()
    for param in params:
        yield scrapy.FormRequest('https://foo.bar/shop', callback=self.addToBasket,
                                 method='POST', formdata=param)


def addToBasket(self, response):
    yield scrapy.FormRequest('https://foo.bar/addToBasket', callback=self.checkoutBasket,
                             method='POST',
                             formdata=param)

def checkoutBasket(self, response):
    yield scrapy.FormRequest('https://foo.bar/checkout', callback=self.final, method='POST',
                             formdata=param)

def final(self):
    print("Success, you have purchased 59 items")

РЕДАКТИРОВАТЬ:

Я пытался сделать запрос в закрытом событии, но он не работает ни на запрос, ни на обратный вызов..

  def closed(self, reason):
        if reason == "finished":
            print("spider finished")
            return scrapy.Request('https://www.google.com', callback=self.finalmethod)
        print("Spider closed but not finished.")

    def finalmethod(self, response):
        print("finalized")

Ответы [ 2 ]

0 голосов
/ 15 июня 2018

Я решил это с помощью сигналов Scrapy и spider_idle call.

Отправляется, когда паук бездействует, что означает, что у паука больше нет:

  • запросов, ожидающих загрузки
  • запросов запланированных элементов
  • , обработанных в конвейере элементов

https://doc.scrapy.org/en/latest/topics/signals.html

from scrapy import signals, Spider

class MySpider(scrapy.Spider):
    name = 'whatever'

    def start_requests(self):
        self.crawler.signals.connect(self.spider_idle, signals.spider_idle) ## notice this
        params = getShopList()
        for param in params:
            yield scrapy.FormRequest('https://foo.bar/shop', callback=self.addToBasket,
                                     method='POST', formdata=param)


    def addToBasket(self, response):
        yield scrapy.FormRequest('https://foo.bar/addToBasket',
                                 method='POST', formdata=param)

    def spider_idle(self, spider): ## when all requests are finished, this is called
        req = scrapy.Request('https://foo.bar/checkout', callback=self.checkoutFinished)
        self.crawler.engine.crawl(req, spider)

    def checkoutFinished(self, response):
        print("Checkout finished")
0 голосов
/ 11 июня 2018

Я думаю, вы можете вручную оформить заказ, когда паук закончил:

def closed(self, reason):
    if reason == "finished":
        return requests.post(checkout_url, data=param)
    print("Spider closed but not finished.")

См. закрыто .

обновить

class MySpider(scrapy.Spider):
    name = 'whatever'

    def start_requests(self):
        params = getShopList()
        for param in params:
            yield scrapy.FormRequest('https://foo.bar/shop', callback=self.addToBasket,
                                     method='POST', formdata=param)


    def addToBasket(self, response):
        yield scrapy.FormRequest('https://foo.bar/addToBasket',
                                 method='POST', formdata=param)

    def closed(self, reason):
        if reason == "finished":
            return requests.post(checkout_url, data=param)
        print("Spider closed but not finished.")
...