我一直试图弄清楚范围和变量在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
我尝试使用全局变量,但是内部设置的变量不会变为全局变量。
如何从回调中获取变量?
答案 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
中。