
我需要先用回调函数 callback 改变类变量,然后使用类变量,但发现程序的实际执行是不等待 yield Request(url,callback)中的 callbak 函数执行完成,便执行其后的语句了。怎么办呢?
写了个程序来表达我的意图:
# -*- coding: utf-8 -*- from scrapy import Spider, Request class ZhihuSpider(Spider): name = "debug_zhihu" allowed_domains = ["www.zhihu.com"] list_for_test = [] def start_requests(self): yield Request('https://www.zhihu.com/people/excited-vczh/following', self.change_list) print('after sent Request statement,list_for_test:', self.list_for_test) # 想打印出“[0,1,2,3,4]”,结果打印出"[]" def change_list(self): for each_item in range(0, 5): self.list_for_test.append(each_item) 1 scb20100708 OP 发现补充中的代码错了,def change_list(self):应是 def change_list(self,response): 改后也输出不了想输出的"[0,1,2,3,4]" |
2 leavic 2017 年 11 月 17 日 把 print 写进 callback 函数的最后。。。。。 |
3 scb20100708 OP 2017 年 11 月 17 日 @leavic 还有别的方法吗?实际代码还有函数“ change_list2 ”也要改变类变量,想在所有改变执行完后再处理类变量。 |
4 860670496 2017 年 11 月 17 日 请参考: https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014317799226173f45ce40636141b6abc8424e12b5fb27000 如果一个函数定义中包含 yield 关键字,那么这个函数就不再是一个普通函数,而是一个 generator: 这里,最难理解的就是 generator 和函数的执行流程不一样。函数是顺序执行,遇到 return 语句或者最后一行函数语句就返回。而变成 generator 的函数,在每次调用 next()的时候执行,遇到 yield 语句返回,再次执行时从上次返回的 yield 语句处继续执行。 所以直接用啃 scrapy 的方法来学 python 不是个好选择,这个坑我也掉过,就是看教程的时候完全是表面上的理解生成器的概念,一用起来就傻了,必须得动手写几个才能彻底明白 |
5 knightdf 2017 年 11 月 17 日 把 yield Request(url,callback)其后的语句放在 callback 的后面执行 |
6 leavic 2017 年 11 月 17 日 @scb20100708 没有什么好方法了,你的需求就应该是把函数放进 callback 里面。 |
7 iyaozhen 2017 年 11 月 17 日 via Android 只能 callback 吧。回调地狱就是那么来的 |
8 scb20100708 OP |
9 hcnhcn012 2017 年 11 月 17 日 via iPhone 机制就是这样,为了效率,要是你 callback 里面花了一个很长时间的的 IO 操作,整个框架都在等你的 callback 然后 yield 带出从而发生阻塞那效率会很低,具体怎么实现的话就要结合 twisted 看源码了 |
10 RadishWind 2017 年 11 月 17 日 还没有实验 加个修饰器行不行?在修饰器中等待? |
11 NLL 2017 年 11 月 17 日 scrapy 是异步的,reuqest 请求也是放进队列的 |
12 larsenlouis 2017 年 11 月 17 日 “回调函数 callback 改变类变量,然后使用类变量” 是发出单个请求->callback 链->print,还是发出所有的请求->完成每个请求的 callback 链->print ? 后者可以用 def spider_closed(self, spider) 参考 https://doc.scrapy.org/en/latest/topics/signals.html |
13 scb20100708 OP |
14 scb20100708 OP @larsenlouis 谢谢,我想要实现的正是你说的“发出所有的请求->完成每个请求的 callback 链->print ? “。 方法可行,谢谢啦。 还找到了一个办法,直接在类中加个函数: def closed(self, reason): print(list_for_test) 参考: https://stackoverflow.com/a/33312325/7011350 |