使用Node.js中的Zombie填充登录表单

5
晚上好!我正在尝试使用zombie.js登录一个网站,但似乎无法让它工作。这个网站是芬兰语的,但不是很难理解,有两个文本字段和一个按钮。第一个是用户名,第二个是密码,按钮是登录按钮。
目前我的登录代码如下:
var Browser = require("zombie");
browser = new Browser();
browser.visit("https://www.nordnet.fi/mux/login/startFI.html?cmpi=start-loggain",
    function () {
        // Here I check the title of the page I'm on.
        console.log(browser.text("title"));
        // Here I fill the needed information.
        browser.document.getElementById("input1").value ="MYUSERNAME";
        browser.document.getElementById("pContent").value ="MYPASSWORD";
        // And here it fails. I try to submit the form in question.
        browser.document.getElementById("loginForm").submit();
        setTimeout(function () {
            // This is here to check that we've submitted the info and have been
            // redirected to a new website.
            console.log(browser.text("title"));
        }, 2000);
});

现在我知道也许应该使用zombie自己的“fill”方法,但我尝试了没有成功,所以我尝试了一些新的方法。

但是所有我得到的结果都是一个错误:

Y:\IMC\Development\Web\node_modules\zombie\lib\zombie\forms.js:72
  return history._submit(_this.getAttribute("action"), _this.getAttribute(
                 ^
TypeError: Cannot call method '_submit' of undefined

现在,如果我记录下 browser.document.getElementById("loginForm") ,它显然找到了表单,但不幸的是,由于某种原因,它不喜欢它。
我也尝试了使用zombie的“传统”方法,即使用网页上的登录按钮并按下它。问题在于,它实际上不是一个按钮,只是一个带有链接的图像,并且所有内容都在 <span> 中。我不知道如何“点击”该按钮。
它没有ID,所以我无法使用它,然后我尝试使用上面的文本,但由于它上面有umlauts,我无法让它起作用。用 /344 转义 ä 只会导致错误:
throw new Error("No BUTTON '" + selector + "'");
        ^
Error: No BUTTON 'Kirjaudu sisään'

所以,那没起作用,但我不知道为什么它无法正确识别转义的umlaut。

这是我的第一个问题,第二个问题很小,但既然我写了这个文本,为什么不在这里问呢。

如果我成功了,我能否复制此登录的cookie,并在我的YQL中使用它来进行屏幕抓取?基本上,我正在尝试抓取股市价值,但如果没有登录,这些价值将被延迟15分钟,这并不太糟糕,但我仍想让它实时。


请查看http://zombie.labnotes.org/。 - John
1个回答

8

经过使用Zombie进行多次测试,我得出结论:它还不够成熟,不能用于严肃的测试。尽管如此,我还是成功地创建了一个表单提交的工作示例(使用常规的.submit()方法)。

var Browser = require("zombie");
var assert = require("assert");

browser = new Browser()
browser.visit("http://duckduckgo.com/", function () {
    // fill search query field with value "zombie"
    browser.fill('input[name=q]', 'mouse');
    // **how** you find a form element is irrelevant - you can use id, selector, anything you want
    // in this case it was easiest to just use built in forms collection - fire submit on element found
    browser.document.forms[0].submit();
    // wait for new page to be loaded then fire callback function
    browser.wait().then(function() {
        // just dump some debug data to see if we're on the right page
        console.log(browser.dump());
    })
});

正如您所见,关键是在提交表单后使用构造函数browser.wait().then(...),否则browser对象仍然会引用初始页面(作为visit方法的参数传递的页面)。注意:即使您不等待页面加载,历史记录对象也将包含您提交表单的页面地址-这让我有点困惑,因为我确信我应该已经看到了新页面。


编辑: 对于您的站点,zombie似乎运行良好(我可以提交表单并获得“错误的登录名或密码”警报)。有一些JS错误,但zombie不会关心它们(但您应该调试这些错误,以查看脚本是否对常规用户有效)。无论如何,以下是我使用的脚本:

var Browser = require("zombie");
var assert = require("assert");

browser = new Browser()
browser.visit("https://www.nordnet.fi/mux/login/startFI.html?cmpi=start-loggain", function () {
    // fill in login field
    browser.fill('#input1', 'zombie');
    // fill in password field
    browser.fill('#pContent', 'commingyourway');
    // submit the form
    browser.document.forms[0].submit();
    // wait for new page to be loaded then fire callback function
    browser.wait().then(function() {
        console.log('Form submitted ok!');
        // the resulting page will be displayed in your default browser
        browser.viewInBrowser();
    })
});

作为附注:当我试图提供可行的示例时,我尝试使用以下页面(所有页面均因不同原因而失败):
  • google.com - 即使我填写了查询框并提交表单,我也没有得到搜索结果。原因?可能是谷歌采取了一些措施,防止自动工具(如僵尸)浏览搜索结果。
  • bing.com - 与谷歌相同 - 提交表单后,我没有得到搜索结果。原因?可能与谷歌相同。
  • paulirish.com - 填写搜索查询框并提交表单后,僵尸遇到了脚本错误,导致无法完成页面(有关缺少来自图表脚本的ActiveX的内容)。
  • perfectionkills.com - 令人惊讶的是,我在Paul Irish网站上遇到了与之相同的问题 - 由于JavaScript错误,无法加载带有搜索结果的页面。
结论:毕竟强制僵尸做你的工作并不容易... :)

确实,zombie似乎相当不完整。我无法让那段代码工作,因为jsdom给我报了一些层次结构错误,但我仍然不知道为什么我不能在我的页面上使用同样的技术。 - Petri Mustonen
你所说的“那段代码”是指我示例中的代码吗?无论如何,如果您的页面对公众开放,请发布链接,我将尝试使用僵尸漫游它 :) - WTK
是的,我指的是你的代码。如果你感兴趣,这是页面链接:https://www.nordnet.fi/mux/login/startFI.html?cmpi=start-loggain。虽然页面是芬兰语的,但页面并不太复杂。只需要输入用户名和密码,然后点击登录按钮即可:p - Petri Mustonen
没问题 - 谷歌翻译来帮忙 ;) 我今天稍后会尝试攻击你的网站。 - WTK
这里有些可疑的事情。首先,那个browser.wait().then似乎什么都没做,它从未记录“表单已提交”部分,viewInBrowser()也是如此,尽管错误提示说它不支持Windows。当我尝试通过使用普通的setTimeout()来规避问题时,它似乎并没有改变网站。在两种情况下(setTimeout()之前和之后),browser.text("title")给出了相同的结果,如果它能够正常工作,后者应该会给出不同的答案。我会继续尝试解决这个问题,但我不喜欢它的行为方式。 - Petri Mustonen
啊!显然我确实进入了错误页面,虽然我不知道为什么,因为登录信息是正确的。但非常感谢你!这帮了我很多! - Petri Mustonen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接