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

AsyncHTMLSession渲染JS动态页时目标div内容为空如何解决

问题根因

#filter-results容器内容为空是两个问题叠加导致的:

  • 你在类里定义的请求头没有实际传给AsyncHTMLSession,默认请求头带明显的自动化工具特征,站点反爬策略直接拦截了攻略列表的数据请求,前端拿不到数据自然不会往容器里渲染内容。
  • 固定sleep的等待逻辑不可靠:该站点是单页应用,hash路由解析、筛选条件匹配、列表接口请求的触发时机不固定,哪怕设置sleep=5,也可能因为接口响应慢、JS执行顺序问题导致你获取页面源码时内容还没加载完成。
解决方案

优先选直接调用站点数据接口的方案,性能高、稳定性强,完全适配discord.py的异步运行场景,不需要跑无头浏览器占内存;如果一定要渲染页面拿内容,用修正后的渲染逻辑即可。

  • 方案1:直接调用站点公开的内容接口(推荐)
    打开浏览器开发者工具抓包就能看到,攻略列表不是前端硬渲染出来的,是页面加载后请求站点原生内容接口拿到结构化数据再渲染的,直接构造异步请求拿JSON数据即可,不用解析HTML、不用等JS渲染。
  • 方案2:修正页面渲染逻辑
    如果必须走页面渲染的路径,补上反爬检测绕过逻辑,把固定sleep改成等待目标容器出现子元素再返回源码,同时把请求头正确传给AsyncHTMLSession,不要全局定义session避免事件循环冲突。
修正后可运行代码
import aiohttp
from requests_html import AsyncHTMLSession

class Scrapper:
    def __init__(self):
        self.headers = {'User-Agent':'Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0'}
        # 不要全局初始化AsyncHTMLSession,放在类实例中避免discord长运行时的事件循环冲突
        self.asession = AsyncHTMLSession(headers=self.headers)
        self.build_api = "https://immortal.maxroll.gg/wp-json/wp/v2/posts"

    # 推荐方案:直接请求接口拿结构化数据
    async def return_build_articles(self, userClass, instance):
        req_params = {
            "categories": 13,
            "per_page": 20,
            "filter_meta_key": f"di-{instance}",
            "filter_taxo_class": f"di-{userClass}"
        }
        async with aiohttp.ClientSession(headers=self.headers) as session:
            async with session.get(self.build_api, params=req_params) as resp:
                raw_data = await resp.json()
                build_list = []
                for build in raw_data:
                    build_list.append({
                        "name": build["title"]["rendered"],
                        "link": build["link"]
                    })
                return build_list

    # 备选方案:页面渲染方式
    async def return_page(self, url):
        resp = await self.asession.get(url)
        # 注入JS绕过无头浏览器检测,等待目标列表容器加载出子元素再返回,不用固定等待
        await resp.html.arender(
            timeout=20,
            waitFor="#filter-results > div",
            script="() => {Object.defineProperty(navigator, 'webdriver', {get: () => false})}"
        )
        list_container = resp.html.find('#filter-results', first=True)
        return list_container

注意:discord机器人长时间运行时尽量不要依赖无头浏览器渲染的方案,这类方案内存占用高,很容易出现进程假死、内存泄漏问题,直接请求接口的方案资源占用只有渲染方案的1%不到,稳定性高很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 03:45:34