Как получить переменную из функции обратного вызова yield в Python - PullRequest
0 голосов
/ 10 января 2019

Я пытался выяснить, как работает область видимости и переменные в Python. Я пытался решить эту проблему, и я не могу найти способ получить переменную из обратного вызова.

def parse1(self,response):
    return 1

def parse2(self,response):
    returned = yield Request(
       'https://www.example.com',
       callback=self.parse1,
       dont_filter=True
      )
    print str(returned)

Возвращает

1

Я пытался работать с глобальными переменными, но переменные внутри него не становятся глобальными.

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

Ответы [ 2 ]

0 голосов
/ 11 января 2019

То, что вы спрашиваете, выглядит довольно специфично для Scrapy, а не для Python, а в Scrapy Spider то, что вы хотите (блокировка запроса на ожидание ответа на другой запрос), не работает таким образом из-за базового механизма Scrapy.
Несмотря на то, что вы можете yield запрос, возвращенный объект Request и его обратный вызов будут обрабатываться только после того, как он будет передан нижележащему механизму, прежде чем вы сможете получить результат Response, переданный вашему другому методу разбора.

Если, OTOH, вы на самом деле просто хотите получить данные из одного метода в другом и «выяснить, как работают области видимости и переменные в Python», просто вызовите его:

def parse1(self,response):
    return 1

def parse2(self,response):
    returned = self.parse1(response)
    print str(returned)

Но я предполагаю, что это не ваша реальная цель, а ваш пример просто плохой.

Вместо этого вам скорее всего нужно дождаться запроса блокировки на parse1, чтобы вернуть результат ответа на parse2, где вы хотите продолжить его обработку. Это не работает в асинхронном мире (это равносильно возвращению во времени), и вы скорее захотите реорганизовать ваш код , чтобы не требовать этот стиль; или если вы зависите от синхронной, блокирующей модели программирования, чтобы использовать что-то, кроме Scrapy.

Однако, как говорится, вы можете взглянуть на scrapy-inline-запросы , которые помогут вам быть ленивым; но чтобы успешно использовать его, вам все равно нужно понимать более глубокую систему Scrapy и проблемы, которые могут возникнуть при ее использовании. Отказ от этого может избавить вас от головной боли в будущем. Считайте себя предупрежденным.
( Определенно прочитайте «Известные проблемы» Readme проекта и Readme здесь: flake8-inline-запросы .)

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

import scrapy
from inline_requests import inline_requests

class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['http://httpbin.org/html']

    @inline_requests  ###<- using this
    def parse(self, response):
        urls = [response.url]
        for i in range(10):
            next_url = response.urljoin('?page=%d' % i)
            try:
                next_resp = yield scrapy.Request(next_url, meta={'handle_httpstatus_all': True})
                ### you can then do that ^^^^^^^
                urls.append(next_resp.url)
            except Exception:
                self.logger.info("Failed request %s", i, exc_info=True)

        yield {'urls': urls}
0 голосов
/ 10 января 2019

Может быть, попытаться поместить данные в meta? Как Request('https://www.example.com', callback=self.parse1, meta={'value': 0}), а затем получить его в parse1 с response.meta.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...