我试图通过PhantomJS登录Aliexpress,但我的脚本不起作用,我无法弄清楚原因。
我正在使用PhantomJS版本2.0.0。
登录表单位于iframe中,可能是问题所在。
这是代码:
var page = new WebPage(), step = 0, loadInProgress = false, timeOut = false;
var url = 'https://login.aliexpress.com/buyer.htm?spm=2114.11040108.1000002.7.8yVuzJ&return=http%3A%2F%2Fcl.aliexpress.com%2F';
填写并提交i-frame内的表格的功能。
var sendForm = function(){
var iframeRef = function( frameRef ) {
return frameRef.contentWindow
? frameRef.contentWindow.document
: frameRef.contentDocument;
};
var iframe = iframeRef(document.getElementById('alibaba-login-box'));
var arr = iframe.getElementById('login-form');
arr.elements["fm-login-id"].value="my-email";
arr.elements["fm-login-password"].value="my-password";
iframe.getElementById('login-form').submit();
console.log("Form submitted.");
};
这些是我的程序遵循的步骤:
var onFinishedSteps = [
//Opens the web to log-in.
function(){
page.open(url);
},
//Fills the form and submits it.
function(){
page.render('0before fill.png');
page.evaluate(sendForm);
page.render('1just after submit.png');
},
//Renders the web ~10 seconds after submitting.
function(){
console.log("timeout setted");
timeOut = true;
window.setTimeout(
function () {
console.log("timeout function");
page.render('2timeout.png');
timeOut = false;
},
10000 // wait 5,000ms (5s)
);
}
];
首先加载网页,然后填写并提交(和呈现)表单。 这两步工作正常。渲染图像正确显示填充的输入(电子邮件和密码)和i帧内容。
第三步应该给程序足够的时间来处理表单和登录,但是渲染的图像仍然显示表单,这次密码输入为空且没有消息(例如'密码错误'或者类似的东西)。
这是该计划的其余部分:
page.onNavigationRequested = function(url, type, willNavigate, main) {
console.log('Trying to navigate to: ' + url);
console.log('Caused by: ' + type);
console.log('Will actually navigate: ' + willNavigate);
console.log('Sent from the page\'s main frame: ' + main);
};
page.onLoadStarted = function() {
loadInProgress = true;
};
page.onLoadFinished = function(status) {
loadInProgress = false;
};
interval = setInterval(function() {
if (!loadInProgress && typeof onFinishedSteps[step] == "function") {
console.log("----------------------- Step " + (step + 1));
onFinishedSteps[step]();
step++;
}
if (!loadInProgress && !timeOut && typeof onFinishedSteps[step] != "function") {
console.log("test complete!");
phantom.exit();
}
}, 50);
如果要测试,请输入完整文件。 Github:https://github.com/xAlstrat/PhantomJsFunctions/blob/master/aliexlogin.js
答案 0 :(得分:1)
我认为问题在于你不能在不同帧(iframe)中的元素上调用函数。你可以尝试一些事情。
使用phantomjs --web-security=false script.js
命令行选项运行PhantomJS:
page.switchToFrame(1); // Try this out
page.evaluate(function(){
var arr = document.getElementById('login-form');
arr.elements["fm-login-id"].value="my-email";
arr.elements["fm-login-password"].value="my-password";
document.getElementById('login-form').submit();
console.log("Form submitted.");
});
在尝试在其中执行某些操作之前,请切换到框架上下文。您可以使用page.switchToFrame()
或其他类似函数通过名称或帧索引更改为帧上下文。例如:
page.switchToFrame(1); // Try this out
page.evaluate(function(){
var arr = document.getElementById('login-form');
arr.elements["fm-login-id"].value="my-email";
arr.elements["fm-login-password"].value="my-password";
arr.elements["fm-login-password"].focus();
});
page.sendEvent("keypress", page.event.key.Enter);
这会产生合成提交事件。
您可以通过使用page.sendEvent()
功能触发输入按键来触发本机提交事件。例如,与之前的建议相似:
page.switchToFrame(1); // Try this out
page.evaluate(function(){
document.getElementById("fm-login-id").focus();
});
page.sendEvent("keypress", "my-email");
page.evaluate(function(){
document.getElementById("fm-login-password").focus();
});
page.sendEvent("keypress", "my-password");
page.evaluate(function(){
document.getElementById("fm-login-password").focus();
});
page.sendEvent("keypress", page.event.key.Enter); // or page.event.key.Return
也许您甚至需要将用户名和密码作为本机事件“键入”字段,因为只需设置字段值不会触发可能在这些元素上注册的任何事件。在提交表单之前,可能会触发可能需要运行的验证:
"content_scripts": [
{
"js": ["Markdown.Converter", "Markdown.Editor", "Markdown.Sanitizer", "previewtab.js"]
}
],