代码之家  ›  专栏  ›  技术社区  ›  Maciek

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

  •  0
  • Maciek  · 技术社区  · 6 年前

    我一直试图弄清楚范围和变量在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 回复  |  直到 6 年前
        1
  •  1
  •   nyov    6 年前

    您所要求的看起来非常具体,而不是python,并且在一个scriby spider中,您想要的(阻止一个请求等待另一个请求的响应)不会以这种方式工作,因为底层scriby机器。
    虽然你可以 yield 一个请求,返回 Request 对象和它的回调只有在传递给底层机器之后才能进行处理,然后才能将响应结果传递给其他分析方法。

    如果您实际上只需要一个方法中的另一个方法的数据,并且“了解范围和变量如何在Python中工作”,那么只需调用它:

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

    但我猜这不是你的敏锐目标,你的榜样也不好。

    相反,您可能要寻找的是等待阻塞请求 parse1 ,将响应结果返回到 parse2 ,继续处理。这在异步世界中不起作用(它等于回到过去),你宁愿 重构代码 不需要这种风格;或者如果你发现自己依赖于一个同步的、阻塞的、编程模型,那么就使用一些除scrapy之外的东西。

    不过,尽管如此,你还是可以看看 scrapy-inline-requests 这将帮助你变得懒惰;但是要成功地使用它,你仍然需要了解更深层次的零碎系统和使用它会产生的问题。避免它可能会在将来减轻你的头痛。 考虑到自己受到警告。
    ( 一定地 阅读项目自述文件的“已知问题”,以及以下自述文件: 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}
    
        2
  •  0
  •   vezunchik    6 年前

    也许试着把数据放进去 meta ?喜欢 Request('https://www.example.com', callback=self.parse1, meta={'value': 0}) 然后把它拿进去 parse1 具有 response.meta .