英文:
Can't convert aiohttp request to text while using rule34 api
问题
我想使用 aiohttp 来向 rule34 API 发出请求,但是当我使用 `text()` 或 `json()` 方法时,程序会冻结:
```python
import aiohttp
import asyncio
async def foo():
async with aiohttp.ClientSession() as session:
r = await session.get('https://api.rule34.xxx/index.php?page=dapi&s=post&q=index&json=1&limit=1000')
print('got response') #ok
text = await r.text() #freezes
print(text) #never reaches
asyncio.run(foo())
但是当我在 URL 中使用 limit=1
时,它正常工作。
而且,使用 requests 库和任何限制值也可以正常工作:
import requests
r = requests.get('https://api.rule34.xxx/index.php?page=dapi&s=post&q=index&json=1&limit=1000')
print(r.text)
我尝试使用调试器,注意到在调用 await r.text()
之前,r._body
为 None
,我需要的数据位于 r.content._buffer
中,看起来像是 deque([b'data'])
,因此我尝试使用它,但后来我注意到数据不完整,就好像没有完全下载:
。
也许是因为 r
没有被等待或者其他原因,但我不能使用 await r
,因为它会抛出异常,或者 await r.text()
,因为它会冻结。所以我甚至找不到发生这种情况的原因。
<details>
<summary>英文:</summary>
I wanted to make a request to rule34 api using aiohttp, but when I use `text()` or `json()` method the program freezes:
```python
import aiohttp
import asyncio
async def foo():
async with aiohttp.ClientSession() as session:
r = await session.get('https://api.rule34.xxx/index.php?page=dapi&s=post&q=index&json=1&limit=1000')
print('got response') #ok
text = await r.text() #freezes
print(text) #never reaches
asyncio.run(foo())
But when I use limit=1
in URL it works normally.
Also it works with requests library with any limit value:
import requests
r = requests.get('https://api.rule34.xxx/index.php?page=dapi&s=post&q=index&json=1&limit=1000')
print(r.text)
I tried to use debugger and noticed that r._body
was None
before await r.text()
was called and the data I need is located at r.content._buffer
and looks like deque([b'data'])
, so I tried to use it, but then I noticed that the data isn't complete, like it isn't downloaded completely:
.
Maybe because of the r
wasn't awaited or I don't know, but I can't use await r
because it throws an exception, or await r.text()
because it freezes. So I can't even find the reason why it happens.
答案1
得分: 0
您与aiohttp
的所有交互都需要在ClientSession
上下文管理器内完成,所以您需要(请注意缩进的更改):
import aiohttp
import asyncio
async def foo():
async with aiohttp.ClientSession() as session:
r = await session.get('https://api.rule34.xxx/index.php?page=dapi&s=post&q=index&json=1&limit=1000')
print('得到响应')
text = await r.text()
print(text)
asyncio.run(foo())
这将成功打印来自API的JSON响应。
英文:
All of your interaction with aiohttp
needs to be inside the ClientSession
context manager, so you need (note the change in indentation):
import aiohttp
import asyncio
async def foo():
async with aiohttp.ClientSession() as session:
r = await session.get('https://api.rule34.xxx/index.php?page=dapi&s=post&q=index&json=1&limit=1000')
print('got response')
text = await r.text()
print(text)
asyncio.run(foo())
This successfully prints a JSON response from the API.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论