0

私はPhantomJSとjavascriptが初めてなので、簡単な解決策があれば許してください。

私は PhantomJS を使用して Web サイトのスクリーンショットを作成しています。特定の DOM ノードを、次のようなリモート JavaScript からの動的コンテンツに置き換えたいと考えています。

<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 に答える