如何等待click()事件加载phantomjs继续之前? [英] How to wait for a click() event to load in phantomjs before continuing?

查看:1674
本文介绍了如何等待click()事件加载phantomjs继续之前?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Phantomjs有这两个真正方便的回调 onLoadStarted onLoadFinished 加载。但我一直在搜索,我找不到一个等价的,如果你 click()提交按钮或超链接。类似的页面加载发生,但 onLoadStarted 没有得到调用这个事件我猜,因为没有一个明确的 page.open() code>发生。我试图找出一个干净的方式暂停执行,而这个负载发生。

Phantomjs has these two really handy callbacks onLoadStarted and onLoadFinished which allow you to essentially pause execution while the page is loading. But I've been searching and I can't find an equivalent for if you click() a submit button or hyperlink. A similar page load happens but onLoadStarted doesn't get called for this event I guess because there isn't an explicit page.open() that happens. I'm trying to figure out a clean way to suspend execution while this load takes place.

一个解决方案显然是嵌套setTimeout的,但我想避免这种情况,它是hacky和依赖于试验和错误,而不是一些可靠和更强大的测试对某事或等待事件。

One solution is obviously nested setTimeout's but I'd like to avoid this scenario because it's hacky and relies on trial and error instead of something reliable and more robust like testing against something or waiting for an event.

有这种页面的特定回调负载,我错过了?或者也许有某种类型的代码模式可以处理这种事情?

Is there a specific callback for this kind of page load that I missed? Or maybe there's some kind of generic code pattern that can deal with this sort of thing?

编辑:

我还没有想出如何让它停顿。下面是当我调用 click()命令时,不调用 onLoadStarted() p>

I still haven't figured out how to get it to pause. Here's the code that doesn't call the onLoadStarted() function when I call the click() command:

var loadInProgress = false;

page.onLoadStarted = function() {
  loadInProgress = true;
  console.log("load started");
};

page.onLoadFinished = function() {
  loadInProgress = false;
  console.log("load finished");
};

page.open(loginPage.url, function (status) {
    if (status !== 'success') {
        console.log('Unable to access network');
        fs.write(filePath + errorState, 1, 'w');
        phantom.exit();
    } else {
        page.evaluate(function (loginPage, credentials) {
            console.log('inside loginPage evaluate function...\n')
            document.querySelector('input[id=' + loginPage.userId + ']').value = credentials.username;
            document.querySelector('input[id=' + loginPage.passId + ']').value = credentials.password;      
            document.querySelector('input[id=' + loginPage.submitId + ']').click();
            //var aTags = document.getElementsByTagName('a')
            //aTags[1].click();
        }, loginPage, credentials);

        page.render(renderPath + 'postLogin.png');
        console.log('rendered post-login');

我仔细检查了id是否正确。 page.render()将显示提交的信息,但只有当我把它放在一个setTimeout(),否则它立即呈现它,我只看到凭证输入,在页面重定向之前。也许我错过了别的东西?

I double checked that the id is correct. The page.render() will show that the information is submitted, but only if I put it in a setTimeout(), otherwise it renders it immediately and I only see the credentials inputted, before the page redirect. Maybe I'm missing something else?

推荐答案

我认为 onLoadStarted onLoadFinished 函数是您需要的一切。以下面的脚本为例:

I think the onLoadStarted and onLoadFinished functions are everything you need. Take for example the following script:

var page = require('webpage').create();

page.onResourceReceived = function(response) {
    if (response.stage !== "end") return;
    console.log('Response (#' + response.id + ', stage "' + response.stage + '"): ' + response.url);
};
page.onResourceRequested = function(requestData, networkRequest) {
    console.log('Request (#' + requestData.id + '): ' + requestData.url);
};
page.onUrlChanged = function(targetUrl) {
    console.log('New URL: ' + targetUrl);
};
page.onLoadFinished = function(status) {
    console.log('Load Finished: ' + status);
};
page.onLoadStarted = function() {
    console.log('Load Started');
};
page.onNavigationRequested = function(url, type, willNavigate, main) {
    console.log('Trying to navigate to: ' + url);
};

page.open("http://example.com", function(status){
    page.evaluate(function(){
        // click
        var e = document.createEvent('MouseEvents');
        e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        document.querySelector("a").dispatchEvent(e);
    });
    setTimeout(function(){
        phantom.exit();
    }, 10000);
});

打印


Trying to navigate to: http://example.com/
Request (#1): http://example.com/
Load Started
New URL: http://example.com/
Response (#1, stage "end"): http://example.com/
Load Finished: success
Trying to navigate to: http://www.iana.org/domains/example
Request (#2): http://www.iana.org/domains/example
Load Started
Trying to navigate to: http://www.iana.org/domains/reserved
Request (#3): http://www.iana.org/domains/reserved
Response (#2, stage "end"): http://www.iana.org/domains/example
New URL: http://www.iana.org/domains/reserved
Request (#4): http://www.iana.org/_css/2013.1/screen.css
Request (#5): http://www.iana.org/_js/2013.1/jquery.js
Request (#6): http://www.iana.org/_js/2013.1/iana.js
Response (#3, stage "end"): http://www.iana.org/domains/reserved
Response (#6, stage "end"): http://www.iana.org/_js/2013.1/iana.js
Response (#4, stage "end"): http://www.iana.org/_css/2013.1/screen.css
Response (#5, stage "end"): http://www.iana.org/_js/2013.1/jquery.js
Request (#7): http://www.iana.org/_img/2013.1/iana-logo-header.svg
Request (#8): http://www.iana.org/_img/2013.1/icann-logo.svg
Response (#8, stage "end"): http://www.iana.org/_img/2013.1/icann-logo.svg
Response (#7, stage "end"): http://www.iana.org/_img/2013.1/iana-logo-header.svg
Request (#9): http://www.iana.org/_css/2013.1/print.css
Response (#9, stage "end"): http://www.iana.org/_css/2013.1/print.css
Load Finished: success


$ b b

它表明,单击链接会发出一次LoadStarted事件和NavigationRequested事件两次,因为有一个重定向。诀窍是在执行动作之前添加事件处理程序:

It shows that clicking a link emits the LoadStarted event once and NavigationRequested event twice, because there is a redirect. The trick is to add the event handlers before doing the action:

var page = require('webpage').create();

page.open("http://example.com", function(status){
    page.onLoadFinished = function(status) {
        console.log('Load Finished: ' + status);
        page.render("test37_next_page.png");
        phantom.exit();
    };
    page.onLoadStarted = function() {
        console.log('Load Started');
    };

    page.evaluate(function(){
        var e = document.createEvent('MouseEvents');
        e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        document.querySelector("a").dispatchEvent(e);
    });
});

如果你需要做这些事情,也许现在是时候尝试 CasperJS 。它运行在PhantomJS的顶部,但有一个更好的API用于导航网页。

If you need to do those things, maybe it is time to try something else like CasperJS. It runs on top of PhantomJS, but has a much better API for navigating web pages.

这篇关于如何等待click()事件加载phantomjs继续之前?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆