Как сделать синхронную обработку запросов - PullRequest
0 голосов
/ 01 марта 2019

Я недавно начал использовать Scrapy и Python, поэтому, пожалуйста, потерпите меня.Я основал свой код из этого учебника .Мне нужно получить информацию из разных городов моей страны (Бразилии) в разные годы с этого сайта .Параметры раскрывающегося списка генерируются динамически с помощью запроса AJAX.Таким образом, сначала я получаю все годы и штаты, затем делаю запрос на получение городов из каждого штата.

Я узнал, что если я использую возврат в моем цикле, как в коде, он завершит мойпроблема заключается в том, что, если я использую YIELD, запрос не следует порядку (возможно, потому что запросы асинхронные? Дайте мне знать причину), то есть он отправляет запрос в город с неправильным состоянием.Поэтому я получаю неправильный ответ.Кстати, несмотря на то, что, используя return, он завершает функцию, он делает правильный запрос.

def parse(self, response):
        years = response.xpath(...).getall()
        states = response.xpath(...).getall()`

        # Start from the second element since the first one is '-- Select --'
        for year in years[1:]:
            for state in states[1:]:
                print (year)
                print (state)        
                # I need this request to get all cities from the current state, since it's generated with an AJAX REQUEST
                request = { ...,
                  callback = self.parse_city
                return request

    def parse_city(self, response):
        keys = response.xpath(...).getall()
        values = response.xpath(...).getall()

        # Build dictionary with the key (city IBGE code) and value (city name)
        cities = dict(zip(keys[1:], values[1:]))

        for code, city in cities.items():
            request = ...,
              callback = self.parse_result
            return request

    def parse_result(self, response):
        yield {
           #The information that I want
        }

Мои запросы создаются внутри цикла, я ожидаю, что произойдет следующее: во-первых: вывести годи государство, а затем сделать запрос.Второе: обратный вызов будет захватывать все города и делать запрос для этого города, в этом штате в этом году.Третье: parse_result выберет информацию, которая мне нужна.Вместо этого происходит то, что он печатает весь год и штат, что означает, что он не выполняется синхронно

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

Заранее большое спасибо

Пытаясь быть более понятным:

for each year   
    select year   
    for each state
        select state
        wait for cities options to load
        for each city
            get the information

1 Ответ

0 голосов
/ 02 марта 2019

Если я правильно понял, проблема здесь в том, что информация о сеансе хранится на сервере с состоянием.Правильно?

Способ справиться с этим будет иметь один сеанс для каждого состояния, управляя им с помощью cookiejars.Например:

for year in years[1:]:
    for state in states[1:]:
        yield Request(
            # ...,
            callback=self.parse_city, 
            meta={'cookiejar': state} 
        )

Дополнительная информация о cookiejars.

И, да, запросы в scrapy запланированы для асинхронного выполнения.Вот почему мы должны предоставить ему функции обратного вызова.

...