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

AsyncHTMLSession返回响应列表无序,如何实现有序返回?

解决requests-html异步请求结果乱序问题

使用requests-html的异步模式结合BeautifulSoup做页面解析,比普通requests工具效率更高,但调用asession.run()执行异步任务时,返回的响应顺序会随请求完成时间变化,而非保持任务提交的固定顺序。不想通过URL作为键构建字典来排序,求更简洁的解决方案,要求响应能稳定保持提交时的顺序。

示例代码

from requests_html import AsyncHTMLSession, HTMLSession, HTMLResponse
from bs4 import BeautifulSoup

asession = AsyncHTMLSession()

async def kucoin():
    print(f'get K')
    r = await asession.get('https://kucoin.com')
    return r

async def gateio():
    print(f'get g')
    r = await asession.get('https://gate.io')
    return r

async def vk():
    print(f'get vk')
    r = await asession.get('https://vk.com')
    return r


tasks = [kucoin, gateio, vk]
results = asession.run(*tasks)
for result in results:
    print(BeautifulSoup(result.text).title)

实际运行结果

get K
get g
get vk
<title>Buy/Sell Bitcoin, Ethereum | Cryptocurrency Exchange | Gate.io</title>
<title>Crypto Exchange | Bitcoin Exchange | Bitcoin Trading | KuCoin</title>
<title>Welcome | VK</title>

更新说明

已确认requests-html返回无序响应是正常设计:AsyncHTMLSession.run()方法内部按任务完成的先后顺序返回结果,而非任务提交的顺序,这是底层异步机制优先返回先完成请求的特性导致的。

解决方案

方案1:给任务绑定索引,按索引排序

直接使用原生asyncio的方式,给每个任务添加索引标识,收集结果后按索引排序,确保顺序和任务提交一致:

import asyncio
from requests_html import AsyncHTMLSession
from bs4 import BeautifulSoup

asession = AsyncHTMLSession()

async def fetch(index, url):
    label = ['K', 'g', 'vk'][index]
    print(f'get {label}')
    r = await asession.get(url)
    return (index, r)

async def main():
    urls = [
        'https://kucoin.com',
        'https://gate.io',
        'https://vk.com'
    ]
    # 创建带索引的异步任务
    tasks = [fetch(i, url) for i, url in enumerate(urls)]
    # 等待所有任务完成
    results = await asyncio.gather(*tasks)
    # 按索引排序,恢复原始顺序
    sorted_results = sorted(results, key=lambda x: x[0])
    # 遍历输出结果
    for _, result in sorted_results:
        print(BeautifulSoup(result.text).title)

if __name__ == '__main__':
    asyncio.run(main())

方案2:封装任务返回标识,自定义排序逻辑

如果需要保留原有的函数结构,可以在每个任务的返回值中加入自定义标识,后续根据标识排序:

from requests_html import AsyncHTMLSession
from bs4 import BeautifulSoup
import asyncio

asession = AsyncHTMLSession()

async def kucoin():
    print(f'get K')
    r = await asession.get('https://kucoin.com')
    return ('kucoin', r)

async def gateio():
    print(f'get g')
    r = await asession.get('https://gate.io')
    return ('gateio', r)

async def vk():
    print(f'get vk')
    r = await asession.get('https://vk.com')
    return ('vk', r)

async def main():
    # 定义原始任务顺序
    task_order = ['kucoin', 'gateio', 'vk']
    tasks = [kucoin(), gateio(), vk()]
    results = await asyncio.gather(*tasks)
    # 按预设顺序排序结果
    sorted_results = sorted(results, key=lambda x: task_order.index(x[0]))
    for _, result in sorted_results:
        print(BeautifulSoup(result.text).title)

if __name__ == '__main__':
    asyncio.run(main())

补充提示

如果一定要使用asession.run(),可以让每个任务返回包含标识的元组,再对asession.run()的返回结果进行排序,逻辑和上述方案一致,但直接使用原生asyncio会更灵活可控。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 06:45:36