0

我是 PhantomJS 和 javascript 的新手,如果有简单的解决方案,请原谅我。

我正在使用 PhantomJS 对网站进行截图,并且我想用来自远程 javascript 的动态内容替换某些 DOM 节点,如下所示:

<script language="JavaScript" src="http://server/dynamic.js" type="text/javascript"></script>

我的第一次尝试:

var page = require('webpage').create();

page.open('http://stackoverflow.com', function (status) {
    if (status !== 'success') {
        phantom.exit();
    }

    page.evaluate(function() {

        //// Case #1: what I really want
        // var s = '<script language="JavaScript" src="http://server/dynamic.js" type="text/javascript"></script>';

        //// Case #2: simple js test case
        // var s = '<script language="JavaScript" type="text/javascript">document.write("<p>THIS IS A TEST</p>");</script>';

        //// Case #3: very simple case
        var s = '<b>THIS IS A TEST</b>';

        var node = document.getElementById('mainbar');
        var pnode = node.parentNode;

        var newele = document.createElement('div');
        newele.innerHTML = s;

        pnode.replaceChild(newele, node);
    });

    page.render('test.jpg');

    phantom.exit();
});

对于我只是用一些文本替换它的简单案例(案例#3),它可以正常工作,但不适用于任何一种 javascript 案例。通过 replaceChild() 插入后,似乎没有对 javascript 进行评估。我在 page.render() 之前尝试了 page.reload() 但它没有帮助。

接下来,我尝试使用 iframe 创建新元素:

var newele = document.createElement('iframe');
newele.setAttribute('src', 'javascript:document.write("<p>THIS IS A TEST</p>");');

这适用于简单的 js 测试用例 #2,但我不知道如何使 iframe 与我真正想要的一起工作(案例 #1)。

有什么建议么?

4

2 回答 2

0

我想出了一个可行的解决方案:

var newele = document.createElement('iframe');
newele.setAttribute('src', 'javascript:document.write("<script src=\'http://server/dynamic.js\'></script>");');

我还不得不延迟一点:

window.setTimeout(function () {
    page.render('test.jpg');
    phantom.exit();
}, 500);

这行得通,但对我来说有点笨拙。我很想听到更好的解决方案。

于 2013-08-09T22:09:31.840 回答
0

不,您可以在第一次调用评估之前将您的 javascript 引用添加到页面中(摘录):

...
        page.open(url, function (status) {
            if (status !== 'success') {
                console.log('Error: Cannot load url. Status: {0}.'.format(status));
                phantom.exit(1);
            } else {
                page.injectJs('../../../code/common/jquery.min.js');
                // call evaluate once to change the dropdown:
                page.evaluate(function (myobj) {
                        // manipulate DOM here with jquery, or whatever you want.
                }, myobj);
...

请注意,您可以多次调用评估,因此您可以从页面中提取内容、从页面中调用 javascript 函数、修改 DOM 等。

于 2014-07-18T22:43:44.390 回答