如何使用PhantomJS提交表单

我试图使用phantomJS(什么是一个很棒的工具btw!)来提交表单,我有login凭据的页面,然后输出目标页面的内容到标准输出。 我能够访问表单并使用幻影成功设置其值,但我不太确定正确的语法是提交表单并输出后续页面的内容。 我到目前为止是:

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(); } 

我想到了。 基本上这是一个asynchronous的问题。 你不能只是提交并期望立即渲染后续页面。 您必须等到触发下一页的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); 

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

CasperJS

更新2015年7月28日添加PhantomJS和CasperJS文章 。

(感谢评论员M先生!)

发送原始POST请求有时可能更方便。 下面您可以看到来自PhantomJS的post.js原始示例

 // 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(); }); 

如上所述, CasperJS是填写和发送表格的最佳工具。 如何使用fill()函数填写和提交表单最简单的例子:

 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(); }); });