用于解析Google搜索结果的Chrome扩展程序不起作用

时间:2012-08-20 18:14:30

标签: google-chrome-extension

我一直在尝试使用Chrome扩展程序机制,并尝试编写一个可以操纵Google搜索结果的扩展程序(添加评论,屏幕截图,收藏夹等)。

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

问题在于它不适用于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");

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

2 个答案:

答案 0 :(得分:2)

“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. 每当添加<a>节点时,函数都会遍历相关节点并修改链接。 (出于显而易见的原因,该脚本忽略了<script>元素。

  4. 此示例扩展程序仅包含~~中链接的文本,但您可以轻松更改它以执行您需要的操作。

    <强>的manifest.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);
    

答案 1 :(得分:0)

我刚写了一个操纵Google搜索结果的扩展程序。似乎问题是结果几乎总是通过AJAX获取。我使用MutationObserver定期检查结果的变化。有两种类型的Google搜索页面(我目前遇到过):标准版和Google即搜即得。对于标准页面,您需要观察body元素(您可以使用选择器“#gsr”),但对于Google Instant,您只需查找包含DIV(“#search”)。您将需要观察childList和子树突变。

(根据@ ExpertSystem的评论编辑)