ProactorEventLoop - ValueError异常:循环参数必须与未来的同意(Pr

2019-09-28 16:29发布

我使用这个异步项目(称为Broker - 请查看git )用下面的代码:

   proxies = asyncio.Queue()
   broker = Broker(proxies)
   tasks = asyncio.gather(broker.find(types = ['HTTPS'], strict = True, limit = 10),
                               self.storeProxies(proxies))
   loop = asyncio.get_event_loop()
   loop.run_until_complete(tasks)

其中self.storeProxies是包含一个异步函数

while True:
    proxy = await proxies.get()
    if proxy is None: break
    self.proxies['http://{0}:{1}'.format(proxy.host, proxy.port)] = 1

不过,我不认为它是与Broker部分(不知道当然)。

每次我运行此代码,成功的相当随机数后,它失败[WinError 10038] An operation was attempted on something that is not a socket 。 然后我试着做一些研究,并结束了在这个答案 。 但有了这个代码努力的时候,我得到这个错误:

ValueError: loop argument must agree with Future

如何处理这个任何想法?

详细信息可能有用:

操作系统:Windows 10(版本1809)的Python版本:3.7.1

基于从米哈伊尔·格拉西莫夫答案

async def storeProxies(self, proxies):
    logger.info("IN IT!")
    while True:
        proxy = await proxies.get()
        if proxy is None: break
        self.proxies['http://{0}:{1}'.format(proxy.host, proxy.port)] = 1

async def getfetching(self, amount):
    from proxybroker import Broker

    proxies = asyncio.Queue()
    broker = Broker(proxies)
    return await asyncio.gather(
        broker.find(
            types = ['HTTP', 'HTTPS'],
            strict = True,
            limit = 10
        ),
        self.storeProxies(proxies)
    )
def fetchProxies(self, amount):
    if os.name == 'nt':
        loop = asyncio.SelectorEventLoop() # for subprocess' pipes on Windows
        asyncio.set_event_loop(loop)
    else:
        loop = asyncio.get_event_loop()
    loop.run_until_complete(self.getfetching(amount))
    logger.info("FETCHING COMPLETE!!!!!!")
    logger.info('Proxies: {}'.format(self.proxies))

其中fetchProxies被称为从另一个地方一定的时间间隔。 这工作完全是第一次,但随后“失败”与警告:

2019-04-06 21:04:21 [py.warnings] WARNING: d:\users\me\anaconda3\lib\site-packages\proxybroker\providers.py:78: DeprecationWarning: The object should be created from async function
  headers=get_headers(), cookies=self._cookies, loop=self._loop

2019-04-06 21:04:21 [py.warnings] WARNING: d:\users\me\anaconda3\lib\site-packages\aiohttp\connector.py:730: DeprecationWarning: The object should be created from async function
  loop=loop)

2019-04-06 21:04:21 [py.warnings] WARNING: d:\users\me\anaconda3\lib\site-packages\aiohttp\cookiejar.py:55: DeprecationWarning: The object should be created from async function
  super().__init__(loop=loop)

其次是这似乎是一个无限循环(硬卡输出没有)行为。 值得注意的是,这种导入时也发生在我身上从格拉西莫夫的例子(在评论) Broker全球。 最后,我开始看到隧道的光。

Answer 1:

看看这一部分:

proxies = asyncio.Queue()

# ...

loop.run_until_complete(tasks)

asyncio.Queue()创建绑定到当前事件循环时(默认事件循环或一个被设置为当前与asyncio.set_event_loop() )。 通常只有循环对象绑定到可以管理它。 如果你改变电流回路,你应该重新创建对象。 同样是许多其他真正asyncio对象。

为了确保每一个对象绑定到新的事件循环,这是更好地创造asyncio已经-相关对象后您设置并运行新的事件循环。 它会是这样的:

async def main():
    proxies = asyncio.Queue()
    broker = Broker(proxies)
    return await asyncio.gather(
        broker.find(
            types = ['HTTPS'], 
            strict = True, 
            limit = amount
        ),
        self.storeProxies(proxies)
    )


if os.name == 'nt':
    loop = asyncio.ProactorEventLoop() # for subprocess' pipes on Windows
    asyncio.set_event_loop(loop)
else:
    loop = asyncio.get_event_loop()
loop.run_until_complete(main())

有时(很少),你必须把里面的一些进口main()两种。


UPD:

问题发生,因为你改变之间的事件循环fetchProxies电话,但Broker进口只有一次(Python的缓存导入模块)。

重装 Broker并没有为我工作,所以我找不到比重用事件循环设置,一旦有更好的方式。

替换此代码

if os.name == 'nt':
    loop = asyncio.SelectorEventLoop() # for subprocess' pipes on Windows
    asyncio.set_event_loop(loop)
else:
    loop = asyncio.get_event_loop()

有了这个

if os.name == 'nt':
    loop = asyncio.get_event_loop()
    if not isinstance(loop, asyncio.SelectorEventLoop):
        loop = asyncio.SelectorEventLoop() # for subprocess' pipes on Windows
        asyncio.set_event_loop(loop)
else:
    loop = asyncio.get_event_loop()

PS

顺便说一句,你不必这样做摆在首位:

if os.name == 'nt':
    loop = asyncio.SelectorEventLoop()
    asyncio.set_event_loop(loop)

窗户已经使用SelectorEventLoop为默认,它不支持管道 ( DOC )。



文章来源: ProactorEventLoop - ValueError: loop argument must agree with Future