簡體   English   中英

我怎樣才能在PhantomJS中等待頁面准備好?

[英]How can I wait for the page to be ready in PhantomJS?

我正在使用PhantomJS登錄網站做某事。 該網站使用OAuth進行登錄。點擊該按鈕上的“登錄”按鈕,即可轉到OAuth服務。 在那里輸入您的憑據並單擊“提交”,您將被重定向回原始站點。 我的腳本工作正常,但依賴於看似不太強大的超時。

我怎樣才能重寫這段代碼,這樣我就可以等到頁面准備好了,而不是使用setTimeout 我經常看到頁面沒有准備好的錯誤,因此jQuery沒有初始化。

我對Javascript不是很好,所以一個例子會有所幫助。 這是我經過大量谷歌搜索后一起攻擊的內容。 這是我的代碼:

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

page.settings.resourceTimeout = 10000;
page.onResourceTimeout = function(e) {
  console.log("Timed out loading resource " + e.url);
};

page.open('https://mysite.com/login', function(status) {
    if (status !== 'success') {
        console.log('Error opening url');
        phantom.exit(1);
    } else {
        setTimeout(function() {
            console.log('Successfully loaded page');
            page.evaluate(function() {
                $("#submit-field").click(); //Clicking the login button
            });

            console.log('Clicked login with OAuth button');
            setTimeout(function() {
                console.log('Addding the credentials');
                page.evaluate(function() {                
                    document.getElementById("username").value = 'user@example.com';
                    document.getElementById("password").value = 'P@ssw0rd';
                    document.getElementById("Login").click();
                });
                console.log('Clicked login button');

                setTimeout(function() {
                    //Inject some jQuery into the page and invoke that here
                    console.log('Clicked the export button');
                }, 15000);
            }, 15000);
        });
    }
});

似乎這樣做的唯一方法是使用從DOM到PhantomJS的回調。

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

page.onInitialized = function() {
    page.onCallback = function(data) {
        console.log('Main page is loaded and ready');
        //Do whatever here
    };

    page.evaluate(function() {
        document.addEventListener('DOMContentLoaded', function() {
            window.callPhantom();
        }, false);
        console.log("Added listener to wait for page ready");
    });

};

page.open('https://www.google.com', function(status) {});

另一種方法是擴展phantomjs waitfor.js示例

我用這種人的方法混合。 這是我的main.js文件:

'use strict';

var wasSuccessful = phantom.injectJs('./lib/waitFor.js');
var page = require('webpage').create();

page.open('http://foo.com', function(status) {
  if (status === 'success') {
    page.includeJs('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js', function() {
      waitFor(function() {
        return page.evaluate(function() {
          if ('complete' === document.readyState) {
            return true;
          }

          return false;
        });
      }, function() {
        var fooText = page.evaluate(function() {
          return $('#foo').text();
        });

        phantom.exit();
      });
    });
  } else {
    console.log('error');
    phantom.exit(1);
  }
});

lib/waitFor.js文件(它只是phantomjs waitfor.js示例中 waifFor()函數的復制和粘貼):

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 condi>
                    clearInterval(interval); //< Stop this interval
                }
            }
        }, 250); //< repeat check every 250ms
}

這個方法不是異步的,但至少我確信在嘗試使用它們之前已經加載了所有資源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM