首页 > 解决方案 > 如何在 javascript 中获取 javascript (emberjs) 呈现的 HTML 源

问题描述

问题:我正在开发一个 javascript 扩展,它需要能够在呈现所有内容后查看页面的源 HTML。问题是无论我使用什么方法,我似乎只能检索到预渲染的源。该网站使用 emberjs 生成页面内容。

示例:站点:https ://www.playstation.com/en-us/explore/games/ps4-games/?console=ps4

当我右键单击并查看源代码时,我会在内容加载之前获取页面。当我右键单击并检查元素时,我想在内容加载后获取源代码。

我试过的:

背景.js

var acceptedURLPattern = "playstation.com";

tabUpdatedCallback = function(tabID, changeInfo, tab) {
    if(tab.url.indexOf(acceptedURLPattern) == -1)   return;

    var eventJsonScript = {
        code: "console.log(\"Script Injected\"); window.addEventListener(\"load\", (event) => { " + browserString + ".runtime.sendMessage({ \"html\": document.documentElement.outerHTML });});"
    };


    browser.tabs.executeScript(tabID, eventJsonScript);
}

handleHTMLMessage = function(request, sender, sendResponse) {
    console.log(request);
}

browser.tabs.onUpdated.addListener(tabUpdatedCallback);
browser.runtime.onMessage.addListener(handleHTMLMessage);

上面的脚本将一个 eventListener 注入到我想要在它触发“load”事件之后获取源的页面上,然后将一条消息发送回包含该源的 background.js。

我尝试将 documentElement 更改为 innerHTML/outerHTML 以及将 eventListener 更改为 document.addEventListener(\"DOMContentLoaded\"),但这些更改似乎都没有任何效果。

我也尝试过使用这些:使用 phantomjs 获取 javascript 呈现的 html 源获取浏览器呈现的 html+javascript但他们使用 phantomjs 加载和执行页面,然后返回 html。在我的解决方案中,我需要能够抓取已经呈现的页面。

我在这里先向您的帮助表示感谢!

编辑#1: 我查看了@wOxxOm 提到的 MutationObserver 并将 eventJsonScript 变量更改为如下所示:

var eventJsonScript = {
    code: "console.log(\"Script Injected\"); var mutationObserver = new MutationObserver( (mutations) => { mutations.forEach((mutation) => {if( JSON.stringify(mutation).indexOf(\"Yakuza\") != -1) { console.log(mutation); } });}); mutationObserver.observe(document.documentElement, {attributes: true, characterData: true, childList: true, subtree: true, attributeOldValue: true, characterDataOldValue: true}); mutationObserver.takeRecords()"
};

然而,尽管该网站显然有一个 Yakuza 6 的部分,但该事件并没有被解雇。我确实删除了注入脚本中的 if 条件以验证事件是否正常触发,它似乎不包含我正在寻找的信息。

标签: javascripthtmlember.jsgoogle-chrome-extensionfirefox-addon

解决方案


所以好消息是有人已经在 Ember 中编写了执行此操作的代码,您可以在这里找到它:

https://github.com/emberjs/ember-test-helpers/blob/031969d016fb0201fd8504ac275526f3a0ab2ecd/addon-test-support/%40ember/test-helpers/settled.js

这是 Ember 测试用来等待所有内容呈现并完成或“解决”的代码。

坏消息是为您的扩展正确提取它是一项不平凡的任务。

基本上,你会想要:

  1. 等到页面加载完毕(window.load 事件)
  2. setTimeout 至少 200 毫秒以确保 Ember 应用程序已启动。
  3. 等到解决,使用上面链接的代码。
  4. 等到浏览器空闲(最新 Chrome 中的 requestIdleCallback 或获取 polyfill)。

希望这有助于您入门。


推荐阅读