from twisted.internet import reactor # 事件循环 相当于selecet作用 监听是否有连接成功(终止条件,所有的socket对象都被移除。)
from twisted.web.client import getPage # socket对象(如果下载完成,自动从事件循环中移除)
from twisted.internet import defer # defer.Deferred 特殊的socket对象(不会发请求,目的是不让事件循环结束,可以手动移除。)
# 1、利用getPage创建socket对象
# 2、将socket对象添加到事件循环中
# 3、开始事件循环(内部发送请求,并接受响应,当所有的socket请求完成后,终止事件循环)
_close = None
count = 0
def response(content): # 回调函数
print(content)
global count
count += 1
if count == 3: # 如果发的三个请求都返回了
_close.callback(None) # 手动移除defer.Deferred,让事件循环结束。
# 表示添加到事件循环中
@defer.inlineCallbacks#进行异步处理
def task():
url = 'http://www.baidu.com' # 相当于scrapy中的start_url
d = getPage(bytes(url.encode("utf-8"))) # 建立连接
d.addCallback(response) # 添加回调函数#执行回调函数 类似scrapy 中的callback函数
url = 'https://www.bilibili.com/' # 类似于scrapy中yield Request中的url
d = getPage(bytes(url.encode("utf-8")))
d.addCallback(response) # 添加回调函数
url = "https://www.taobao.com/"
d = getPage(bytes(url.encode("utf-8")))
d.addCallback(response) # 添加回调函数
global _close
_close = defer.Deferred() # 把特殊的socket对象赋值给全局变量_close
yield _close
def stop(*args, **kwargs):
reactor.stop()
spider1 = task() # 开启socket
spider2 = task() # 开启socket
dd = defer.DeferredList([spider1, spider2]) # 把爬虫放到列表中监听
dd.addBoth(stop) # 如果socket都完成则调用事件循环结束的函数
reactor.run() # 开始事件循环
注意:addCallback()方法C要大写
步骤:首先先把task()这个函数放到defer.inlineCallbacks装饰器进行异步处理,在task()里先发请求,运行回调函数,最后产生出defer.Deferred这种不发请求的特殊socket对象,把task()的返回的对象放入到defer.DeferredList进行监听,如果当一个socket对象发的所有请求都返回后只剩下defer.Deferred在事件循环中,手动把defer.Deferred这个对象移除,defer.DeferredList监听到事件循环为空了,就自动关闭事件循环。