【问题标题】:Chrome extension to parse Google results doesn't work用于解析 Google 结果的 Chrome 扩展程序不起作用
【发布时间】:2012-08-20 18:14:30
【问题描述】:

我一直在试验 Chrome 扩展机制,并一直在尝试编写一个可以操纵 Google 结果的扩展(添加 cmets、屏幕截图、网站图标等)

到目前为止,我已经设法编写了一个使用 RegEx 将 imgs 添加到链接的代码,并且工作正常。

问题在于它不适用于 Google 搜索结果。 我读到here 是因为页面没有完全加载而发生的;所以我添加了一个 'DOMContentLoaded' 监听器,但它没有帮助。

这是我的代码(内容脚本):

function parse_google()  {
document.body.innerHTML = document.body.innerHTML.replace(
        new RegExp("<a href=\"(.*)\"(.*)</a>", "g"),
        "<img src=\"http://<path-to-img.gif>\" /><a href=\"$1\"$2</a>"
    );
alert("boooya!");
};
alert("content script: before");
document.addEventListener('DOMContentLoaded', parse_google(), false);    
alert("content script: end");

我收到所有“警报”,但它不适用于谷歌。为什么?

【问题讨论】:

  • 正则表达式显示不好,但它有效。它所做的只是在有 标签的地方添加一个 标签。
  • 不完全清楚问题是什么,因为您提供的链接似乎可以解决您的问题。如果您提出一个比“您能提供建议”更具体的问题,您会得到更好的答案。
  • 迈克,感谢您的回答。问题是我遵循了那里演示的方法,但并没有解决问题。我仍然不能让我的正则表达式影响谷歌结果。提前致谢。
  • 你试过听 DOMNodeInserted 吗?

标签: google-chrome-extension


【解决方案1】:

“DOMContentLoaded”是指页面的静态HTML,但是Google的搜索结果是使用AJAX获取的,因此在触发“DOMContentLoaded”事件时还没有。

您可以改用 MutationObserver 来观察根节点及其后代上的“childList”DOM 突变。
(如果您选择这种方法,mutation-summary library 可能会派上用场。)

经过(非常浅薄的)搜索后,我发现(至少对我而言)Google 将其结果放在div 中,id search。以下是执行以下操作的示例扩展的代码:

  1. 注册一个 MutationObserver 以检测 od div#search 插入 DOM。

  2. 注册 MutationObserver 以检测 div#search 及其后代中的“childList”变化。

  3. 每当添加&lt;a&gt; 节点时,函数都会遍历相关节点并修改链接。 (出于显而易见的原因,该脚本忽略了 &lt;script&gt; 元素。

此示例扩展名只是将链接文本包含在 ~~ 中,但您可以轻松更改它以执行任何您需要的操作。

ma​​nifest.json:

{
    "manifest_version": 2,
    "name":    "Test Extension",
    "version": "0.0",

    "content_scripts": [{
        "matches": [
            ...
            "*://www.google.gr/*",
            "*://www.google.com/*"
        ],
        "js":         ["content.js"],
        "run_at":     "document_end",
        "all_frames": false
    }],

}

content.js:

console.log("Injected...");

/* MutationObserver configuration data: Listen for "childList"
 * mutations in the specified element and its descendants */
var config = {
    childList: true,
    subtree: true
};
var regex = /<a.*?>[^<]*<\/a>/;

/* Traverse 'rootNode' and its descendants and modify '<a>' tags */
function modifyLinks(rootNode) {
    var nodes = [rootNode];
    while (nodes.length > 0) {
        var node = nodes.shift();
        if (node.tagName == "A") {
            /* Modify the '<a>' element */
            node.innerHTML = "~~" + node.innerHTML + "~~";
        } else {
            /* If the current node has children, queue them for further
             * processing, ignoring any '<script>' tags. */
            [].slice.call(node.children).forEach(function(childNode) {
                if (childNode.tagName != "SCRIPT") {
                    nodes.push(childNode);
                }
            });
        }
    }
}

/* Observer1: Looks for 'div.search' */
var observer1 = new MutationObserver(function(mutations) {
    /* For each MutationRecord in 'mutations'... */
    mutations.some(function(mutation) {
        /* ...if nodes have beed added... */
        if (mutation.addedNodes && (mutation.addedNodes.length > 0)) {
            /* ...look for 'div#search' */
            var node = mutation.target.querySelector("div#search");
            if (node) {
                /* 'div#search' found; stop observer 1 and start observer 2 */
                observer1.disconnect();
                observer2.observe(node, config);

                if (regex.test(node.innerHTML)) {
                    /* Modify any '<a>' elements already in the current node */
                    modifyLinks(node);
                }
                return true;
            }
        }
    });
});

/* Observer2: Listens for '<a>' elements insertion */
var observer2 = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (mutation.addedNodes) {
            [].slice.call(mutation.addedNodes).forEach(function(node) {
                /* If 'node' or any of its desctants are '<a>'... */
                if (regex.test(node.outerHTML)) {
                    /* ...do something with them */
                    modifyLinks(node);
                }
            });
        }
    });
});

/* Start observing 'body' for 'div#search' */
observer1.observe(document.body, config);

【讨论】:

    【解决方案2】:

    我刚刚编写了一个扩展来操纵 Google 搜索结果。似乎问题在于结果几乎总是通过 AJAX 获取。我使用MutationObserver 定期检查结果的变化。有两种类型的 Google 搜索页面(到目前为止我遇到过):标准和 Google Instant。对于标准页面,您需要观察正文元素(您可以使用选择器“#gsr”),但对于 Google Instant,您可以只查找包含的 DIV(“#search”)。你会想要观察 childList 和 subtree 的变化。

    (根据@ExpertSystem 的 cmets 编辑)

    【讨论】:

    • setInterval 对于这个任务来说太过分了。请改用 MutationObserver。
    • MutationObserver 的问题是在某些情况下结果元素及其父元素还不存在。我想它仍然可以完成,但它需要更复杂的编码。
    • 身体总是存在的,所以你去寻找一个祖先:)(99.9% 的时间有一些父容器从一开始就存在于层次结构中更深。
    • 正确 - 现在只是为了弄清楚为什么观察者没有在 Google.com 上触发
    • 谁说它没有开火?
    猜你喜欢
    • 2021-02-23
    • 2012-06-03
    • 1970-01-01
    • 2014-06-01
    • 2013-12-28
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    相关资源
    最近更新 更多