You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用aiohttp调用Rule34 API时无法转换请求结果为文本

使用aiohttp调用Rule34 API时大请求冻结的问题

我尝试用aiohttp调用Rule34 API,当调用text()或json()方法时程序直接冻结:

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())

但把URL里的limit=1时程序能正常运行,而且用requests库不管limit设多大都没问题:

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里但没完全下载,试了await r也没用,不知道原因出在哪。


问题原因与解决办法

核心问题:会话关闭过早

你在async with aiohttp.ClientSession()的缩进块外面调用r.text(),这时候会话已经被关闭了。aiohttp的响应对象依赖会话的连接来完成数据下载,会话关闭后,剩余的响应数据无法继续读取,导致程序卡在await r.text()。

requests库是同步的,调用get()时已经把整个响应数据下载完成了,所以不存在这个问题;而limit=1时数据量极小,可能在会话关闭前就已经完成了数据下载,所以不会冻结。

修复代码

把读取响应的代码放到async with 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('got response')
        text = await r.text() # 现在能正常读取
        print(text)

asyncio.run(foo())

额外优化建议

  • 直接用await r.json()来解析JSON响应,比先转文本再解析更高效:
data = await r.json()
  • 可以设置超时时间,避免长时间无响应:
r = await session.get(url, timeout=aiohttp.ClientTimeout(total=30))

内容的提问来源于stack exchange,提问作者Ogurchik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:07:05