我尝试了各种JavaScript技术来触发提交按钮.为了满足“Just use JQuery”的用户群,我也试过了.什么都行不通.当我在测试脚本的末尾渲染表单时,我看到填充了数据的表单耐心地等待< search>按钮被点击.
以下是我尝试过的摘要:
> document.getElementById(‘btnSearch’).click();
> $(“btnSearch”).click();
> var el = document.getElementById(‘btnSearch’); //获取搜索按钮对象
$(EL).点击();
> document.getElementById(‘Form1’).submit();
>尝试创建一个单击事件并从按钮对象中触发它(在下面的代码中)
>尝试创建一个单击事件并使用相关按钮内部点的坐标从主体对象中触发它
这是表格:
(并且请不要对缺乏CSS,使用表格等进行评论/辩论.我对创建该网站的人没有任何发言权或影响力.)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <HTML> <HEAD> <title>Da Site</title> </HEAD> <body> <form name="Form1" method="post" action="Default.aspx" id="Form1"> <TABLE id="Table2" cellSpacing="2" cellPadding="1" border="0"> <TR> <TD>Street Address:</TD> <TD><input name="Address" type="text" maxlength="100" id="Address" /></TD> </TR> <TR> <TD>City:</TD> <TD><input name="City" type="text" maxlength="100" id="City" style="width:232px;"/></TD> </TR> <TR> <TD>State:</TD> <TD><select name="State" id="State"> <option value=""></option> <option value="AL">AL - Alabama</option> <option value="AK">AK - Alaska</option> [The rest of the other states] <option value="WI">WI - Wisconsin</option> <option value="WY">WY - Wyoming</option> <option value="PR">PR - Puerto Rico</option> </select> </TD> </TR> <TR> <TD>Zip Code:</TD> <TD><input name="ZipCode" type="text" maxlength="5" id="ZipCode" /></TD> </TR> <tr> <td><input type="submit" name="btnSearch" value="Search" id="btnSearch" /> <input type="submit" name="btnReset" value="Reset" id="btnReset" /> </td> </tr> </TABLE> </form> </body> </HTML>
这是驱动表单的JavaScript:
var maxtimeOutMillis = 3000; var start; var finish; var page = require('webpage').create(); // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") page.onConsoleMessage = function(msg) { console.log(msg); }; page.open('http://www.MadeUpURL.com/',function(status) { page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js",function() { if (status !== 'success') { console.log('Unable to access network'); } else { page.render('before.png'); // Renders the blank form page.evaluate( function () { // page.render('Sample.png'); document.getElementById('Address').value = '123 Somewhere Drive'; document.getElementById('City').value = 'Somewhere'; document.getElementById('State').selectedIndex = 36; document.getElementById('ZipCode').value = '12345'; // I've done a page.render() here and it shows the form fully and correctly populated // Now let's submit the form... var el = document.getElementById('btnSearch'); // Get the "search" button object // Tried the usual suspects document.getElementById('btnSearch').click(); $("btnSearch").click(); $(el).click(); document.getElementById('Form1').submit(); // Tried creating a click event and firing it from the button object var ev = document.createEvent("MouseEvent"); ev.initMouseEvent("click",true /* bubble */,true /* cancelable */,window,null,/* coordinates */ false,false,/* modifier keys */ 0 /*left click*/,null); el.dispatchEvent(ev); // Tried calculating the location of the button itself (which works) and fire the click event from the <Body> object var obj = document.getElementById('btnSearch'); var x = obj.offsetLeft; var y = obj.offsetTop; while (obj.offsetParent) { x = x + obj.offsetParent.offsetLeft; y = y + obj.offsetParent.offsetTop; if (obj == document.getElementsByTagName("body")[0]) { break; } else { obj = obj.offsetParent; } } x = x + 5; // Tried with and without this +5 delta y = y + 5; // Tried with and without this +5 delta console.log('X = ' + x); console.log('Y = ' + y); var ev = document.createEvent("MouseEvent"); ev.initMouseEvent("click",x,y,null); document.body.dispatchEvent(ev); }); start = new Date().getTime(); finish = new Date().getTime(); console.log('Time before: ' + start); // Check to see if results are defined (or times out) while ( (finish - start < maxtimeOutMillis) && !( page.evaluate( function() {return document.getElementById('TheAnswer');}))) { finish = new Date().getTime(); } console.log('Time after: ' + finish); if ( page.evaluate( function() {return document.getElementById('TheAnswer');})) { console.log(page.evaluate( function() {return document.getElementById('TheAnswer').textContent;})); } else { console.log('Element not defined'); } } page.render('after.png'); phantom.exit(); }); });
我希望这是你忘记分号的东西之一,但我只是看不到它.任何帮助将非常感谢!
C:\Temp\WebAutomation\PhantomJS\scripts>phantomjs interact.js X = 151 Y = 442 Time before: 1407875912197 [edit #2 - change before/after labels to match code] Time after: 1407875915197 Element not defined C:\Temp\WebAutomation\PhantomJS\scripts>
解决方法
由this post from Vinjay Boyapati提供,问题似乎更多地与页面处理程序和排序有关.似乎在PhantomJS中处理页面转换的最佳方法是启动页面循环(单击提交按钮,链接等)并退出该JS评估函数.在检查PhantomJS以确保页面已完全加载并且稳定之后,请调用另一个页面.评估并查找浏览器取回提交结果时您希望找到的内容.这是我从Vinjay的帖子中复制/修改的代码:
编辑:要特别注意的一件事.对于每个page.Evaluates(),其中需要jQuery,我正在添加page.injectJs(“jquery1-11-1min.js”);线.否则我会得到“$is undefined”作为页面错误.
var page = require('webpage').create(); var loadInProgress = false; var testindex = 0; // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") page.onConsoleMessage = function(msg) { console.log(msg); }; page.onAlert = function(msg) { console.log('alert!!> ' + msg); }; page.onLoadStarted = function() { loadInProgress = true; console.log("load started"); }; page.onLoadFinished = function(status) { loadInProgress = false; if (status !== 'success') { console.log('Unable to access network'); phantom.exit(); } else { console.log("load finished"); } }; var steps = [ function() { page.open('http://www.MadeUpURL.com'); },function() { page.injectJs("jquery1-11-1min.js"); page.evaluate(function() { document.getElementById('Address').value = '302 E Buchtel Avenue'; //University of Akron if you're wondering document.getElementById('City').value = 'Akron'; document.getElementById('State').selectedIndex = 36; document.getElementById('ZipCode').value = '44325'; console.log('JQ: ' + $().jquery); $('#btnSearch').click(); console.log('Clicked'); }); },function() { console.log('Answers:'); page.injectJs("jquery1-11-1min.js"); page.render('AnswerPage.png'); page.evaluate(function() { console.log('The Answer: ' + document.getElementById('TheAnswer').innerHTML); $('#buttonOnAnswerPage').click(); // This isn't really necessary unless you need to navigate deeper console.log('Sub button clicked'); }); },function() { console.log('More Answers:'); // This function is for navigating deeper than the first-level form submission page.render('MoreAnswersPage.png'); page.evaluate(function() { console.log('More Stuff: ' + document.body.innerHTML); }); },function() { console.log('Exiting'); } ]; 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);