scrapy 自动终止事件循环

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监听到事件循环为空了,就自动关闭事件循环。

猜你喜欢

转载自blog.csdn.net/u014248032/article/details/83116296