在Chrome扩展程序中反复抓取DOM

时间:2013-12-17 01:56:25

标签: google-chrome dom google-chrome-extension content-script message-passing

我正在努力教自己如何编写Chrome扩展程序,当我意识到我的jQuery因为从扩展页面本身获取信息而不是像我预期的那样从标签的当前页面获取信息时,我遇到了麻烦。 / p>

快速摘要,我的示例扩展将每隔x秒刷新一次页面,查看内容/ DOM,然后用它做一些事情。第一个和最后一个部分都很好,但是从我所在的页面获取DOM已经证明非常困难,而且文档对我来说并不是非常有用。

您可以在以下链接中查看我目前的代码:

Current manifest

Current js script

Current popup.html

如果我希望能够在setInterval调用的每个循环中获取DOM,还需要做什么?我知道,例如,我需要一个内容脚本。但我是否还需要在清单中指定背景页面?我需要在哪里调用扩展程序中的内容脚本?在每次重新加载时,让它与我当前的js文件进行通信的最简单/最好的方法是什么?我的内容脚本是否也期望我使用jQuery?

我知道这些问题是基本的,回想起来对我来说似乎微不足道,但他们真的很难接受我自己完全探索。提前谢谢。

1 个答案:

答案 0 :(得分:1)

要访问网页DOM,您需要 programmatically inject some code (使用 chrome.tabs.executeScript() )。

尽管如此,虽然可以将DOM作为字符串抓取,但将其传递回弹出窗口,将其加载到新元素中并查找您想要的内容,这是一种非常糟糕的方法(出于各种原因) 。
最佳选择(在效率和准确性方面)是在网页本身进行处理,然后将结果传递回弹出窗口。请注意,为了能够将代码注入网页,您必须在清单中的permissions属性中包含相应的 host match pattern

我上面描述的内容可以这样实现:

editorMarket.js

var refresherID = 0;
var currentID = 0;

$(document).ready(function(){
    $('.start-button').click(function(){
        oldGroupedHTML = null;
        oldIndividualHTML = null;

        chrome.tabs.query({ active: true }, function(tabs) {
            if (tabs.length === 0) {
                return;
            }

            currentID = tabs[0].id;
            refresherID = setInterval(function() {
                chrome.tabs.reload(currentID, { bypassCache: true }, function() {
                    chrome.tabs.executeScript(currentID, {
                        file:      'content.js',
                        runAt:     'document_idle',
                        allFrames: false
                    }, function(results) {
                        if (chrome.runtime.lastError) {
                            alert('ERROR:\n' + chrome.runtime.lastError.message);
                            return;
                        } else if (results.length === 0) {
                            alert('ERROR: No results !');
                            return;
                        }

                        var nIndyJobs  = results[0].nIndyJobs;
                        var nGroupJobs = results[0].nGroupJobs;
                        $('.lt').text('Indy: ' + nIndyJobs + '; '
                                      + 'Grouped: ' + nGroupJobs);
                    });
                });
            }, 5000);
        });
    });

    $('.stop-button').click(function(){
        clearInterval(refresherID);
    });
});

content.js:

(function() {
    function getNumberOfIndividualJobs() {...}
    function getNumberOfGroupedJobs() {...}

    function comparator(grouped, individual) {
        var IndyJobs = getNumberOfIndividualJobs();
        var GroupJobs = getNumberOfGroupedJobs();

        nIndyJobs = IndyJobs[1];
        nGroupJobs = GroupJobs[1];
        console.log(GroupJobs);

        return {
            nIndyJobs: nIndyJobs, 
            nGroupJobs: nGroupJobs
        };
    }

    var currentGroupedHTML = $(".grouped_jobs").html();
    var currentIndividualHTML = $(".individual_jobs").html();
    var result = comparator(currentGroupedHTML, currentIndividualHTML);
    return result;
})();