【问题标题】:Phantom JS :first-child returning correct results half the time?Phantom JS:first-child 一半时间返回正确结果?
【发布时间】:2016-02-07 17:58:29
【问题描述】:

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

我正在尝试将生成的飞机头顶图图像保存在页面上

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

The image I should be getting everytime

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

非常感谢任何可以为我指明正确方向的人。

虽然截取到页面区域的屏幕截图会起作用,但航班开销列表通常会缩小和扩大 - 很难设置包含所有结果的静态大小。

如果在 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);

    }

});

【问题讨论】:

    标签: javascript css-selectors phantomjs screenshot wolframalpha


    【解决方案1】:

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

    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 &gt; :first-child)。您可以将所需的两个元素的尺寸与正确的clipRect 结合起来。

    【讨论】:

    • Artjom,非常感谢您!它现在完美运行。真正的天才!
    • 这似乎停止工作了?我有一个类似的问题,这就是为什么我选择#answers 而不是 Result 或 Input。 @ 987654322@ TypeError:null 不是对象(评估 'document.querySelector('#Input').getBoundingClientRect') undefined:2 :3 TypeError:null 不是对象(评估 'document.querySelector('#Result' ).getBoundingClientRect') undefined:2 :3 TypeError: null is not an object (evalating 'clipRect.top') phantomjs://code/stack33.js:14
    • 我应该说我使用的是静态超时功能。工作近 24 小时后出现此错误。我已经循环运行 phantomjs 24 小时了,今晚它终于给了我这个错误。我重新启动了运行 phantomjs 的批处理文件,现在一切都很好,它正在更新。也许我会设置更长的超时时间并设置运行 phantomjs 的批处理文件,在几个小时后退出并让调度程序将其恢复,这样错误就不会继续。无论哪种方式,你在这里给了我足够的东西来实现我需要的东西,比我以前拥有的东西要好得多。再次感谢!
    • 我认为这与页面加载所需的时间有关。我注意到页面现在需要很长时间才能加载到这个 IP 地址。我想知道我的请求是否使他们的服务器超载并且它的响应是减慢我的访问速度。
    • 可能是 Wolframalpha 减慢了您的速度,但您可以将第二个 sn-p 的 10 秒超时增加到 30 秒或更多秒。 waitFor 保证一旦元素存在就会停止。
    猜你喜欢
    • 1970-01-01
    • 2014-09-25
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 2012-04-11
    • 2016-04-08
    相关资源
    最近更新 更多