如何从Python的yield回调函数中获取变量

时间:2019-01-10 14:12:49

标签: python scrapy

我一直试图弄清楚范围和变量在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 :(得分:1)

您要问的内容看起来非常特定于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-requests,这将帮助您变得懒惰;但是要成功使用它,您仍然需要了解更深入的Scrapy系统以及使用此系统可能出现的问题。避免它可能会在将来为您省去头痛。 考虑一下自己。
肯定请阅读项目自述文件的“已知问题”,以及此处的自述文件:flake8-inline-requests。)

使用此方法,可以有内联请求,避免编写多个解析方法,如下所示:

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}

答案 1 :(得分:0)

也许尝试将数据放入meta中?像Request('https://www.example.com', callback=self.parse1, meta={'value': 0})一样,然后用parse1放在response.meta中。