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

如何在多线程环境下使用requests-html渲染异步页面?

解决requests-html异步场景下arender()不生效的问题

嘿,我看到你遇到了一个头疼的问题:用AsyncHTMLSession的arender()渲染动态页面,但返回的HTML还是初始的空表格,根本没加载JS生成的内容。问题出在你把异步会话和线程池混用了,这直接打乱了requests-html的JS渲染机制。

为啥会这样?

AsyncHTMLSession本身就是为asyncio异步场景设计的,它的arender()方法依赖asyncio的事件循环来启动无头浏览器执行JS。但你用loop.run_in_executor()把异步的fetch函数丢进了线程池,相当于把异步代码放到了独立线程里跑,这会导致arender()无法正确绑定主事件循环,JS渲染过程压根没触发,自然拿不到渲染后的内容。

修复后的正确代码

我们只需要去掉多余的ThreadPoolExecutor,用AsyncHTMLSession原生的异步方式来处理请求就好:

from pprint import pprint
import asyncio
from requests_html import AsyncHTMLSession

async def fetch(session, url):
    r = await session.get(url)
    # 给渲染加个超时时间,确保JS有足够时间加载表格内容
    await r.html.arender(timeout=20)
    return r.html.html  # 返回渲染后的完整HTML文本

def parseWebpage(page):
    # 这里可以换成你实际的解析逻辑,比如提取表格数据
    if '<table' in page:
        print("✅ 成功获取到渲染后的表格内容!")
    # 打印前1000个字符看看效果
    pprint(page[:1000])

async def get_data_asynchronous():
    urls = [
        'http://www.fpb.pt/fpb2014/!site.go?s=1&show=jog&id=258215'
    ]
    async with AsyncHTMLSession() as session:
        # 直接创建异步任务列表
        tasks = [fetch(session, url) for url in urls]
        # 并发执行所有任务并收集结果
        responses = await asyncio.gather(*tasks)
        for response in responses:
            parseWebpage(response)

def main():
    # 用asyncio.run()简化事件循环管理(Python 3.7+支持)
    asyncio.run(get_data_asynchronous())

if __name__ == "__main__":
    main()

一些额外的小建议

  • 如果要爬多个URL,直接往urls列表里加就行,asyncio.gather()会自动帮你并发处理
  • 可以给arender()加浏览器参数来优化性能,比如禁用图片加载:
    await r.html.arender(timeout=20, options={'args': ['--no-sandbox', '--disable-images']})
    
  • 如果遇到渲染超时,适当调大timeout参数,确保JS有足够时间加载动态内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:45:07