首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Python和AsyncIO获取JSON

使用Python和AsyncIO获取JSON
EN

Stack Overflow用户
提问于 2018-11-07 23:06:20
回答 3查看 15.7K关注 0票数 5

不久前,我开始学习异步。我遇到了一个问题。我的代码不会终止。我搞不懂。请救救我!

代码语言:javascript
复制
import signal
import sys
import asyncio
import aiohttp
import json

loop = asyncio.get_event_loop()
client = aiohttp.ClientSession(loop=loop)

async def get_json(client, url):
    async with client.get(url) as response:
        assert response.status == 200
        return await response.read()

async def get_reddit_cont(subreddit, client):
    data1 = await get_json(client, 'https://www.reddit.com/r/' + subreddit + '/top.json?sort=top&t=day&limit=50')

    jn = json.loads(data1.decode('utf-8'))

    print('DONE:', subreddit)

def signal_handler(signal, frame):
    loop.stop()
    client.close()
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

for key in {'python':1, 'programming':2, 'compsci':3}:
    asyncio.ensure_future(get_reddit_cont(key, client))
loop.run_forever()

结果:

代码语言:javascript
复制
DONE: compsci  
DONE: programming  
DONE: python  
...

我试图取得一些成就,但结果并不稳定。

代码语言:javascript
复制
future = []
for key in {'python':1, 'programming':2, 'compsci':3}:
    future=asyncio.ensure_future(get_reddit_cont(key, client))
loop.run_until_complete(future)

结果(1项任务而不是3项任务):

代码语言:javascript
复制
DONE: compsci  
[Finished in 1.5s]  

我用这种方式解决了我的问题:

加上:

代码语言:javascript
复制
async with aiohttp.ClientSession () as a client:

AT:

代码语言:javascript
复制
async def get_reddit_cont (subreddit, client):  

和:

代码语言:javascript
复制
if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    futures = [get_reddit_cont(subreddit,client) for subreddit in range(1,6)]
    result = loop.run_until_complete(asyncio.gather(*futures))

但是,当代码完成后,我会得到这样的信息:

代码语言:javascript
复制
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x034021F0>
[Finished in 1.0s]

我不明白为什么会这样。

但是,当我尝试执行"for key“大约60次或更多次时,我会得到一个错误:

..。 aiohttp.client_exceptions.ClientOSError: WinError 10054远程主机强制终止现有连接

EN

Stack Overflow用户

回答已采纳

发布于 2018-11-07 23:28:03

答案就在你的代码里。这是loop.run_forever()的线索。因此,您需要调用loop.stop()。我将使用诸如if子句或while循环之类的条件。

代码语言:javascript
复制
if we_have_what_we_need:
    signal_handler(signal, frame)

代码语言:javascript
复制
while we_dont_have_what_we_need:
    loop.forever()

第一个将在满足条件时停止您的代码。后者将继续下去,直到满足条件为止。

更新

我们也可以使用;

(Python文档)

代码语言:javascript
复制
loop.run_until_complete(future)

运行到未来(未来的一个实例)已经完成。 如果参数是coroutine对象,则隐式地将其作为asyncio.Task运行。 返回未来的结果或提出其异常。

代码语言:javascript
复制
loop.run_forever()

运行事件循环,直到调用stop()为止。

票数 2
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53199248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档