首页 文章

如何使用PhantomJS提交表格

提问于
浏览
160

我正在尝试使用phantomJS(这是一个很棒的工具btw!)为我有登录凭据的页面提交表单,然后将目标页面的内容输出到stdout . 我能够使用幻像访问表单并成功设置其值,但我不太确定提交表单和输出后续页面内容的正确语法 . 到目前为止我所拥有的是:

var page = new WebPage();
var url = phantom.args[0];

page.open(url, function (status) {

  if (status !== 'success') {
      console.log('Unable to access network');
  } else {

    console.log(page.evaluate(function () {

      var arr = document.getElementsByClassName("login-form");
      var i;

      for (i=0; i < arr.length; i++) {

        if (arr[i].getAttribute('method') == "POST") {
          arr[i].elements["email"].value="mylogin@somedomain.com";
          arr[i].elements["password"].value="mypassword";

          // This part doesn't seem to work. It returns the content
          // of the current page, not the content of the page after 
          // the submit has been executed. Am I correctly instrumenting
          // the submit in Phantom?
          arr[i].submit();
          return document.querySelectorAll('html')[0].outerHTML;
        }

      }

      return "failed :-(";

    }));
  }

  phantom.exit();
}

4 回答

  • 6

    我想到了 . 基本上这是一个异步问题 . 您不能只提交并期望立即呈现后续页面 . 您必须等到触发下一页的onLoad事件 . 我的代码如下:

    var page = new WebPage(), testindex = 0, loadInProgress = 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("https://website.com/theformpage/");
      },
      function() {
        //Enter Credentials
        page.evaluate(function() {
    
          var arr = document.getElementsByClassName("login-form");
          var i;
    
          for (i=0; i < arr.length; i++) { 
            if (arr[i].getAttribute('method') == "POST") {
    
              arr[i].elements["email"].value="mylogin";
              arr[i].elements["password"].value="mypassword";
              return;
            }
          }
        });
      }, 
      function() {
        //Login
        page.evaluate(function() {
          var arr = document.getElementsByClassName("login-form");
          var i;
    
          for (i=0; i < arr.length; i++) {
            if (arr[i].getAttribute('method') == "POST") {
              arr[i].submit();
              return;
            }
          }
    
        });
      }, 
      function() {
        // Output content of page to stdout after form has been submitted
        page.evaluate(function() {
          console.log(document.querySelectorAll('html')[0].outerHTML);
        });
      }
    ];
    
    
    interval = setInterval(function() {
      if (!loadInProgress && typeof steps[testindex] == "function") {
        console.log("step " + (testindex + 1));
        steps[testindex]();
        testindex++;
      }
      if (typeof steps[testindex] != "function") {
        console.log("test complete!");
        phantom.exit();
      }
    }, 50);
    
  • 18

    此外,CasperJS为PhantomJS中的导航提供了一个很好的高级界面,包括点击链接和填写表格 .

    CasperJS

    更新为添加July 28, 2015 article comparing PhantomJS and CasperJS .

    (感谢M先生的评论者!)

  • 61

    发送原始POST请求有时可能更方便 . 下面你可以看到PhantomJS的post.js original example

    // Example using HTTP POST operation
    
    var page = require('webpage').create(),
        server = 'http://posttestserver.com/post.php?dump',
        data = 'universe=expanding&answer=42';
    
    page.open(server, 'post', data, function (status) {
        if (status !== 'success') {
            console.log('Unable to post!');
        } else {
            console.log(page.content);
        }
        phantom.exit();
    });
    
  • 223

    如上所述CasperJS是填写和发送表单的最佳工具 . 使用fill() function填写和提交表单的最简单示例:

    casper.start("http://example.com/login", function() {
    //searches and fills the form with id="loginForm"
      this.fill('form#loginForm', {
        'login':    'admin',
        'password':    '12345678'
       }, true);
      this.evaluate(function(){
        //trigger click event on submit button
        document.querySelector('input[type="submit"]').click();
      });
    });
    

相关问题