Javascript 使用PhantomJS登录并加载网站,无需硬编码计时

Javascript 使用PhantomJS登录并加载网站,无需硬编码计时,javascript,phantomjs,Javascript,Phantomjs,我有一个工作脚本,看起来有点 var page = require('webpage').create(); page.onConsoleMessage = function(msg) { console.log(msg); }; page.open("http://www.any_website.com", function(status) { if ( status == "success" ) { page.evaluate(function() {

我有一个工作脚本,看起来有点

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

page.onConsoleMessage = function(msg) {
    console.log(msg);
};


page.open("http://www.any_website.com", function(status) {
    if ( status == "success" ) {
        page.evaluate(function() {
              document.querySelector("input[name='MAIL_ADDRESS']").value = "any@mail.com";
              document.querySelector("input[name='PASSWORD']").value = "the_real_password";
              document.getElementsByName("LOGIN_FORM_SUBMIT")[0].click();
              console.log("Login submitted!");
        });
        window.setTimeout(function () {
            var ua = page.evaluate(function () {
                return document.getElementById('ContentMain').innerHTML;
            });
            console.log(ua);
            phantom.exit();
        }, 20000);
   }
});
尽可能好

但正如您可能看到的,我在单击登录按钮后20秒内实现了一个修复超时。我想摆脱这一点,我希望脚本关闭后立即登录完成。我已经玩了好几个月了,但如果没有时间限制,我无法找到一个更优雅、更高效、更健壮的解决方案

有人能帮忙修改代码吗

谢谢

PS:欢迎提供更多关于javascript+phantomjs功能的信息。我真的不知道我在这里做什么,也不知道第二个page.evaluate调用是否有意义

PPS:是否有延迟功能等待站点完全加载

编辑1:

谢谢你的评论。我可以精确地说“完全加载”是指定义的字符串将出现在数据中。我尝试了另一种方法,使用setInterval循环并在html数据中查找特定字符串

此新代码不起作用,因为脚本在步骤1后挂起。我想当我读出page.content值时,整个phantomjs处理停止,我不会提前获取page.content,登录后任何时候都不会获取最新数据

该计划只是轮询html数据,只要我找到一个特定的字符串,我知道该字符串将在加载站点时出现

当我将间隔提高到5000或更高时,可能是因为在最终数据出现后调用了page.content,所以脚本可以工作?!(不确定,但这是我的解释)

知道如何在不中断/停止站点下载/处理的情况下轮询html数据吗

if (!String.prototype.includes) {
  String.prototype.includes = function(search, start) {
    'use strict';
    if (typeof start !== 'number') {
      start = 0;
    }

    if (start + search.length > this.length) {
      return false;
    } else {
      return this.indexOf(search, start) !== -1;
    }
  };
}

var page = require('webpage').create(), testindex = 0, loadInProgress = false, delayedLoad = false;

page.onConsoleMessage = function(msg) {
    console.log(msg);
};

page.onLoadStarted = function() {
  loadInProgress = true;
  console.log("load started");
};

page.onLoadFinished = function() {
  loadInProgress = false;
  console.log("load finished");
};

var steps = [
  function() {
    //Load Login Page
    page.open("http://www.any_website.com");
  },
  function() {
    //Enter Credentials and login
    page.evaluate(function() {
      document.querySelector("input[name='MAIL_ADDRESS']").value = "real_name";
      document.querySelector("input[name='PASSWORD']").value = "real_password";
      document.getElementsByName("LOGIN_FORM_SUBMIT")[0].click();
    });
  }, 
  function() {
    // Output content of page to stdout after form has been submitted
    page.render('out.png');
    page.evaluate(function() {
      console.log(document.getElementById('ContentMain').innerHTML);
    });
  }
];

// this is for signalizing phantomjs when all the data has finished loading
var stepstop = [ "", "Stop Text at the End of the needed Data", ""];



interval = setInterval(function() {
  if (!loadInProgress && typeof steps[testindex] == "function") {
    if (delayedLoad == false) {
      console.log("step " + testindex);
      steps[testindex]();
    }

    if (stepstop[testindex] != "") {
      var tempHTML = page.content;
          // console.log("b " + tempHTML.length);
          console.log("c " + stepstop[testindex]);
          // console.log("d " + tempHTML);
          console.log("e " + tempHTML.includes(stepstop[testindex]));
      if (tempHTML.includes(stepstop[testindex]) != false) {
        console.log("step " + testindex + ": HTML stop found");
        delayedLoad = false;
        testindex++;
      } else {
        console.log("step " + testindex + ": HTML stop not found");
        delayedLoad = true;
      }
    } else {
      console.log("step " + testindex + ": no HTML stop search needed");
      testindex++;
    }
  }

  if (typeof steps[testindex] != "function") {
    console.log("shutdown phantom");
    phantom.exit();
  }
}, 100);

好的。。。最后我找到了一个解决办法

我完全从phantomjs切换到Selenium+Webdriver(Chrome浏览器)+C#API

这对我来说效果更好,它允许实现更复杂的机制来查找用户定义的“load finished”标准


也许只是我,但对于PhantomJS和JavaScript,我没有找到解决方案。

看这里:-如果我没有弄错的话,这可以解决您的问题。这两种方法的可能重复是最好的:和。当然,您始终可以重复使用
waitFor
来等待表示页面已完全加载的特定选择器。此外,如何定义“完全加载”?或者只使用setInterval而不是setTimeout并检查某些条件