Phantom JS:第一个孩子一半时间返回正确的结果?

时间:2016-02-07 06:29:56

标签: javascript css-selectors phantomjs screenshot wolframalpha

我从PhantomJS得到的结果只有一半是正确的。

我正在尝试在页面上保存生成的平面顶部图表图像

http://www5b.wolframalpha.com/input/?i=planes+overhead+90210

The image I should be getting everytime

我花了很多时间才达到这一点,现在已经停留了几天。似乎没有办法使用queryselector图像,所以这是我能想到的最好的。我认为它有效,但结果只有一半的时间。

非常感谢任何能够指出我正确方向的人。

虽然缩小到页面区域的屏幕截图会起作用,但是飞行开销列表经常缩小和扩展 - 这使得很难设置包含所有结果的静态大小。

如果在java脚本(或特别是PhantomJS)中有一种方法可以通过Id或Class选择图像而不是元素,这将有很大帮助。

我们正在使用此图像覆盖远程天文台的360直播摄像机。我们看到很多飞机在成像过程中通过摄像头,能够知道当前的开销是多么好。

var page = require('webpage').create();
page.viewportSize = {
    width : 650,
    height : 480
};
page.open('http://www5b.wolframalpha.com/input/?i=planes+overhead+90210', function (status) {

    just_wait();

    var clipRect = page.evaluate(function () {
        return document.querySelector('#answers:first-child').getBoundingClientRect();
    });

    page.clipRect = {
        top : clipRect.top,
        left : clipRect.left,
        width : clipRect.width,
        height : clipRect.height
    };

    function just_wait() {

        setTimeout(function () {

            page.render('flightsoverhead.png');

            phantom.exit();

        }, 3200);

    }

});

1 个答案:

答案 0 :(得分:0)

您遇到的问题是因为您没有等待加载页面,因为某些元素是异步加载的。您可以像这样等待一段静态时间:

var page = require('webpage').create();
page.viewportSize = { width: 650, height: 480 };
page.open('http://www5b.wolframalpha.com/input/?i=planes+overhead+90210', function (status) {

    setTimeout(function() {
        var clipRect = page.evaluate(function(){
            return document.querySelector('#Input').getBoundingClientRect();
        });
        var clipRectResult = page.evaluate(function(){
            return document.querySelector('#Result').getBoundingClientRect();
        });

        page.clipRect = {
            top:    clipRect.top,
            left:   clipRect.left,
            width:  clipRect.width,
            height: clipRect.height + clipRectResult.height
        };
        console.log(JSON.stringify(clipRect));
        page.render('flightsoverhead.png');

        phantom.exit();
    }, 5000);
});

或者您可以使用waitFor()等待元素加载

function waitFor(testFx, onReady, timeOutMillis) {
    var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
        start = new Date().getTime(),
        condition = false,
        interval = setInterval(function() {
            if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
                // If not time-out yet and condition not yet fulfilled
                condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
            } else {
                if(!condition) {
                    // If condition still not fulfilled (timeout but condition is 'false')
                    console.log("'waitFor()' timeout");
                    phantom.exit(1);
                } else {
                    // Condition fulfilled (timeout and/or condition is 'true')
                    console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
                    typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
                    clearInterval(interval); //< Stop this interval
                }
            }
        }, 250); //< repeat check every 250ms
};


var page = require('webpage').create();
page.viewportSize = { width: 650, height: 480 };
page.open('http://www5b.wolframalpha.com/input/?i=planes+overhead+90210', function (status) {
    var clipRect;
    waitFor(function _check() {
        clipRect = page.evaluate(function(){
            return {
                input: document.querySelector('#Input').getBoundingClientRect(),
                result: document.querySelector('#Result').getBoundingClientRect(),
            };
        });
        return clipRect && clipRect.input && clipRect.input.height > 50 && clipRect.result && clipRect.result.height > 50;
    }, function _onReady(){
        page.clipRect = {
            top:    clipRect.input.top,
            left:   clipRect.input.left,
            width:  clipRect.input.width,
            height: clipRect.input.height + clipRect.result.height 
        };
        page.render('flightsoverhead2.png');

        phantom.exit();
    }, 10000);

});

当您查看标记时:

<section id="answers">
    <section id="Input">...</section>
    <section id="Result">...</section>
    <section id="SkyMap:FlightData">...</section>
</section>

您对#Input#Result感兴趣,因此使用:first-child是不够的(顺便说一句,#answers:first-child会选择一个#answers元素本身就是第一个孩子,你想使用#answers > :first-child)。您可以将所需的两个元素的尺寸组合为正确的clipRect