0

Я получаю результаты от PhantomJS, которые верны только в половине случаев.Phantom JS: первый ребенок возвращает правильные результаты в половине случаев?

Я пытаюсь сохранить полученные самолеты над головой изображение графика на странице

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

The image I should be getting everytime

Я потратил много часов, попадающих в этот момент и теперь несколько дней застряли в эта точка. По-видимому, не существует способа использовать queryselector для изображений, поэтому это было лучшее, что я мог придумать. Я думал, что это сработало, но результаты работают только в половине случаев.

Большое спасибо всем, кто может указать мне в правильном направлении.

В то время как снимок экрана, разрезанный на область страницы, будет работать, список накладных расходов рейсов иногда сжимается и расширяется, что затрудняет установку статического размера, который будет охватывать все результаты.

Если в сценарии java (или PhantomJS) есть способ выбрать изображения вместо элементов по идентификатору или классу, которые помогут много.

Мы используем это изображение для наложения на живую 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); 

    } 

}); 

ответ

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 sele cts a #answers элемент, который сам по себе является первым ребенком, вы хотели использовать #answers > :first-child). Вы можете комбинировать размеры двух элементов, которые вы хотите, для правильного clipRect.

+0

Artjom, Большое вам спасибо за это! Теперь он отлично работает. Настоящий гений! – user3311917

+0

Казалось, это перестало работать? У меня была аналогичная проблема, и именно поэтому я выбрал #answers для результата или ввода. http://www5b.wolframalpha.com/scripts/wa.min.js?v=1.0.0&bt=1602081404:3 TypeError: null не является объектом (оценка 'document.querySelector (' # Input ') .g etBoundingClientRect ') неопределенными: 2 : 3 TypeError: нуль не является объектом (оценка 'document.querySelector (' # Результат') getBoundingClientRect ') неопределенным:. 2 : 3 TypeError: null - это не объект (оценка «clipRect.top ') phantomjs: //code/stack33.js: 14 – user3311917

+0

Я должен сказать, что я использовал функцию статического тайм-аута. Эта ошибка возникла после работы в течение почти 24 часов. Я бегаю phantomjs в цикле в течение 24 часов, и сегодня вечером он, наконец, дал мне эту ошибку. Я перезапустил пакетный файл с phantomjs, и теперь все хорошо, его обновление. Возможно, я установил более длительный тайм-аут и установил командный файл, который запускает phantomjs, чтобы выйти через несколько часов, и планировщик вернет его, чтобы ошибка не продолжалась. В любом случае, вы дали мне достаточно для достижения того, что мне нужно, намного лучше, чем раньше. Еще раз спасибо! – user3311917