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

使用JSDOM获取Rarible集合页面渲染后HTML元素的问题求助

如何用JSDOM获取Rarible页面脚本渲染后的完整HTML

Rarible是React构建的单页应用(SPA),初始返回的HTML只有基础骨架,所有页面内容都是客户端脚本动态生成的。你当前的代码虽然开启了脚本执行,但没有等脚本完成渲染、DOM更新完毕就立刻序列化,所以拿到的是未渲染的初始内容。

修复方案

1. 修正JSDOM参数格式

你之前把配置拆成了多个对象传入,JSDOM.fromURL只接受URL和一个options对象,所有配置要合并到一起:

JSDOM.fromURL("https://rarible.com/collection/" + collection, {
  runScripts: "dangerously",
  pretendToBeVisual: true,
  resources: "usable"
})

2. 等待页面渲染完成

必须等脚本执行完、DOM更新后再序列化,下面两种方法任选:

方法一:等待window的load事件

监听load事件,确保所有资源和脚本都执行完毕:

JSDOM.fromURL("https://rarible.com/collection/" + collection, {
  runScripts: "dangerously",
  pretendToBeVisual: true,
  resources: "usable"
}).then(dom => {
  return new Promise((resolve) => {
    dom.window.addEventListener('load', () => {
      resolve(dom);
    });
  });
}).then(dom => {
  const rendered = dom.serialize();
  res.status(200).json([{ rendered }]);
});

方法二:等待特定元素出现(更精准)

如果知道页面渲染后一定会出现某个元素(比如藏品列表容器),用MutationObserver监听DOM变化,直到目标元素出现再序列化:

JSDOM.fromURL("https://rarible.com/collection/" + collection, {
  runScripts: "dangerously",
  pretendToBeVisual: true,
  resources: "usable"
}).then(dom => {
  return new Promise((resolve) => {
    const doc = dom.window.document;
    // 替换成页面实际存在的目标元素选择器,比如藏品列表容器
    const targetSelector = ".collection-items";

    // 先检查元素是否已加载
    if (doc.querySelector(targetSelector)) {
      resolve(dom);
      return;
    }

    // 监听DOM变化
    const observer = new dom.window.MutationObserver(() => {
      if (doc.querySelector(targetSelector)) {
        observer.disconnect();
        resolve(dom);
      }
    });

    observer.observe(doc.body, { childList: true, subtree: true });

    // 设置10秒超时,避免无限等待
    setTimeout(() => {
      observer.disconnect();
      resolve(dom);
    }, 10000);
  });
}).then(dom => {
  const rendered = dom.serialize();
  res.status(200).json([{ rendered }]);
});

3. 额外注意事项

  • runScripts: "dangerously"会执行页面所有脚本,有安全风险,仅在可信网站使用。
  • 部分SPA会检测环境,JSDOM的模拟可能被识别,可添加浏览器特征伪装:
    const dom = await JSDOM.fromURL("https://rarible.com/collection/" + collection, {
      runScripts: "dangerously",
      pretendToBeVisual: true,
      resources: "usable",
      userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
    });
    // 补充浏览器属性
    dom.window.navigator.deviceMemory = 8;
    dom.window.navigator.hardwareConcurrency = 8;
    
  • 如果JSDOM还是无法正确渲染,改用Puppeteer(无头浏览器),它模拟真实Chrome环境,对SPA支持更好:
    const puppeteer = require('puppeteer');
    
    (async () => {
      const browser = await puppeteer.launch();
      const page = await browser.newPage();
      await page.goto("https://rarible.com/collection/" + collection, { waitUntil: 'networkidle2' });
      const rendered = await page.content();
      res.status(200).json([{ rendered }]);
      await browser.close();
    })();
    

内容的提问来源于stack exchange,提问作者Ted's Projects

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 02:41:03