【问题标题】:How to call a button's onClick() method in PhantomJS?如何在 PhantomJS 中调用按钮的 onClick() 方法?
【发布时间】:2017-01-10 05:40:09
【问题描述】:

这不是重复的。我查看了PhantomJS; click an element 中的答案,OP 说答案是调用分配给需要的元素的“onClick()”方法点击了,但 OP 没有说他们是如何做到这一点的。也没有可接受的答案。

我正在尝试使用 PhantonJS 脚本自动将 Android 应用程序提交到亚马逊的应用程序商店。到目前为止,我有这些步骤:

  1. 打开开发者控制台 URL:https://developer.amazon.com/login.html
  2. 登录我的开发者帐户
  3. 点击 add_new_app_link
  4. 填充First App提交表单,然后调用定义在该元素上的onclick方法:

麻烦的是第 4 步。代码如下:

    function(apptitle,category){
            page.evaluate(function(apptitle,category){
                    document.getElementById('title').value=apptitle;
                    var sel = document.querySelector('select');
                    sel.selectedIndex = 16;
                    sanitizeManifestURL();
            },apptitle,category);
            page.render('step4.png');
            console.log(page.content);
    },

我使用 console.log() 转储生成的 HTML,它相当长,所以我创建了这个 pastebin:http://pastebin.com/kjg6XqSW

这是我生成的屏幕截图。

我应该注意的另一件事是,我可以通过 Chrome 浏览器的开发者控制台让按钮工作。

更新 1:

感谢伊戈尔,但我仍然无法点击按钮。这是整个脚本:

//
//  Run this script like so:
//
//       phantomjs --cookies-file=cookys.txt example_amazon_login.js 'myemailaddress@gmail.com' 'mypasswordshhhh'
//
//       You may need to execute the script twice so that the cookys.txt file gets data written to it.
//       See https://stackoverflow.com/questions/41391254/not-able-to-get-phantomjs-example-to-work
//


var steps=[];
var testindex = 0;
var loadInProgress = false;//This is set to true when a page is still loading

/*********SETTINGS*********************/
var username = 'unknown';
var password = 'unknown';
var apptitle = 'unknown';
var category = 'Music & Audio';

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

/*
page.onResourceRequested = function(request) {
  console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function(response) {
 console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
*/

page.onError = function(msg, trace) {

  var msgStack = ['ERROR: ' + msg];

  if (trace && trace.length) {
    msgStack.push('TRACE:');
    trace.forEach(function(t) {
      msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
    });
  }

  console.error(msgStack.join('\n'));

};

page.settings.userAgent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36';
page.settings.javascriptEnabled = true;
page.settings.loadImages = false;//Script is much faster with this field set to false
phantom.cookiesEnabled = true;
phantom.javascriptEnabled = true;
/*********SETTINGS END*****************/


/* Get command line args user password*/
var system = require('system');
var args = system.args;
var initial_url = 'https://developer.amazon.com/login.html';

if (args.length === 1) {
  console.log('Try to pass some arguments when invoking this script!');
} else {
  args.forEach(function(arg, i) {
    console.log(i + ': ' + arg);
    if ( i === 1 ) { username = arg; }
    if ( i === 2 ) { password = arg; }
    if ( i === 3 ) { apptitle = arg; }
  });
}

if ( username == 'unknown' ) {
        console.log('Please specify username and password');
        phantom.exit();
}
if ( password == 'unknown' ) {
        console.log('Please specify username and password');
        phantom.exit();
}
if ( apptitle == 'unknown' ) {
        console.log('Please specify apptitle');
        phantom.exit();
}


console.log('All settings loaded, start with execution');
page.onConsoleMessage = function(msg) {
    console.log(msg);
};
/**********DEFINE STEPS THAT FANTOM SHOULD DO***********************/
steps = [

        /*
         * Step 1 - Open Amazon home page
         */
        function(){
                console.log('Step 1 - Open Amazon home page ' + initial_url);
                // page.open("https://developer.amazon.com/home.html", function(status) {
                page.open( initial_url, function(status) {
                        console.log('status is '+ status );
                });
        },

        /*
         * Step 2 - Populate and submit the login form
         */
        function(username,password){
                console.log('Step 2 - Populate and submit the login form');
                // var appActionToken = page.evaluate(function() { return $('input[name="appActionToken"]').attr('value'); });
                // console.log( 'appActionToken is ' + appActionToken );
                console.log( 'username is ' + username );
                console.log( 'password is ' + password );
                page.evaluate(function(username,password){
                        console.log( '  username is ' + username );
                        console.log( '  password is ' + password );
                        document.getElementById("ap_email").value=username;
                        document.getElementById("ap_password").value=password;
                        document.getElementById("ap_signin_form").submit();
                },username, password);
        },
        /*
         * Step 3 Click the add_new_app button
         */
        function(){
                console.log('Step 3 - Click on the add_new_app button');
                page.evaluate(function(){
                        var evnt = document.createEvent("MouseEvents");
                        evnt.initEvent("click",true,true);
                        document.getElementById("add_new_app_link").dispatchEvent(evnt);

                });
                //page.render('step3.png');
        },

        /*
         * Step 4 - Populate and submit the First App submission vorm
         *
         * <input id="submit_button" type="submit" class="button large primary one-click-submit" name="save" value="Save" onclick="sanitizeManifestURL()">
         *
         * try looking here:
         * https://stackoverflow.com/questions/32771609/how-to-click-on-selectbox-options-using-phantomjs
         *
         */

        function(apptitle,category,click){
                console.log('Step 4 - save app ' + apptitle);
                page.evaluate(function(apptitle,category,click){
                        document.getElementById('title').value=apptitle;
                        var sel = document.querySelector('select');
                        sel.selectedIndex = 16;
                        // this works
                        var evt = document.createEvent("HTMLEvents");
                        evt.initEvent("change", false, true);
                        sel.dispatchEvent(evt);

                        //The form will be submitted, by click on the button:
                        click('#submit_button');
                },apptitle,category,click);

//              setTimeout(function(){
                        page.render('step4.png');
//                      console.log(page.content);
//              },200);
        }
];

/**********END STEPS THAT FANTOM SHOULD DO***********************/

//Execute steps one by one
interval = setInterval(executeRequestsStepByStep,50);
function click(sel){
        var event=document.createEvent('MouseEvents');
        event.initMouseEvent('click',1,1,window,1,0,0,0,0,0,0,0,0,0,null);
        document.querySelector(sel).dispatchEvent(event);
}

function executeRequestsStepByStep(){
    if (loadInProgress == false && typeof steps[testindex] == "function") {
        console.log("testindex is " + testindex );
        if ( testindex == 1 ) {
                console.log( "username is " + username );
                steps[testindex](username, password);
        } else if ( testindex == 3 ) {
                steps[testindex](apptitle, category, click);
        } else {
            steps[testindex]();
        }
        testindex++;
    }
    if (typeof steps[testindex] != "function") {
        console.log("test complete!");
        phantom.exit();
    }
}

/**
 * These listeners are very important in order to phantom work properly.
 * Using these listeners, we control loadInProgress marker which controls, weather a page is fully loaded.
 * Without this, we will get content of the page, even a page is not fully loaded.
 */
page.onLoadStarted = function() {
    loadInProgress = true;
    console.log('Loading started');
};
page.onLoadFinished = function() {
    loadInProgress = false;
    console.log('Loading finished');
};
page.onConsoleMessage = function(msg) {
    console.log(msg);
};

【问题讨论】:

  • 什么不起作用? document.querySelector('#submit_button').click(); 有效,您要提交该表格吗?
  • 您是如何让按钮通过 Chrome 浏览器的开发者控制台工作的?我需要代码..
  • 感谢您的回复伊戈尔。抱歉,我能够通过 Chrome 开发人员控制台让 document.querySelector('submit_button').click() 工作。我会更新我的问题。

标签: javascript phantomjs


【解决方案1】:

PhantomJS 在工作完成之前退出。
步骤完成后,我们需要等待。

//
//  Run this script like so:
//
//       phantomjs --cookies-file=cookys.txt example_amazon_login.js 'myemailaddress@gmail.com' 'mypasswordshhhh'
//
//       You may need to execute the script twice so that the cookys.txt file gets data written to it.
//       See http://stackoverflow.com/questions/41391254/not-able-to-get-phantomjs-example-to-work
//


var steps=[];
var testindex = 0;
var loadInProgress = false;//This is set to true when a page is still loading

/*********SETTINGS*********************/
var username = 'unknown';
var password = 'unknown';
var apptitle = 'unknown';
var category = 'Music & Audio';

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

/*
page.onResourceRequested = function(request) {
  console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function(response) {
 console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
*/

page.onError = function(msg, trace) {

  var msgStack = ['ERROR: ' + msg];

  if (trace && trace.length) {
    msgStack.push('TRACE:');
    trace.forEach(function(t) {
      msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
    });
  }

  console.error(msgStack.join('\n'));

};

page.settings.userAgent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36';
page.settings.javascriptEnabled = true;
page.settings.loadImages = false;//Script is much faster with this field set to false
phantom.cookiesEnabled = true;
phantom.javascriptEnabled = true;
/*********SETTINGS END*****************/


/* Get command line args user password*/
var system = require('system');
var args = system.args;
var initial_url = 'https://developer.amazon.com/login.html';

if (args.length === 1) {
  console.log('Try to pass some arguments when invoking this script!');
} else {
  args.forEach(function(arg, i) {
    console.log(i + ': ' + arg);
    if ( i === 1 ) { username = arg; }
    if ( i === 2 ) { password = arg; }
    if ( i === 3 ) { apptitle = arg; }
  });
}

if ( username == 'unknown' ) {
        console.log('Please specify username and password');
        phantom.exit();
}
if ( password == 'unknown' ) {
        console.log('Please specify username and password');
        phantom.exit();
}
if ( apptitle == 'unknown' ) {
        console.log('Please specify apptitle');
        phantom.exit();
}


console.log('All settings loaded, start with execution');
page.onConsoleMessage = function(msg) {
    console.log(msg);
};
/**********DEFINE STEPS THAT FANTOM SHOULD DO***********************/
steps = [

        /*
         * Step 1 - Open Amazon home page
         */
        function(){
                console.log('Step 1 - Open Amazon home page ' + initial_url);
                // page.open("https://developer.amazon.com/home.html", function(status) {
                page.open( initial_url, function(status) {
                        console.log('status is '+ status );
                });
        },

        /*
         * Step 2 - Populate and submit the login form
         */
        function(username,password){
                console.log('Step 2 - Populate and submit the login form');
                // var appActionToken = page.evaluate(function() { return $('input[name="appActionToken"]').attr('value'); });
                // console.log( 'appActionToken is ' + appActionToken );
                console.log( 'username is ' + username );
                console.log( 'password is ' + password );
                page.evaluate(function(username,password){
                        console.log( '  username is ' + username );
                        console.log( '  password is ' + password );
                        document.getElementById("ap_email").value=username;
                        document.getElementById("ap_password").value=password;
                        document.getElementById("ap_signin_form").submit();
                },username, password);
        },
        /*
         * Step 3 Click the add_new_app button
         */
        function(){
                console.log('Step 3 - Click on the add_new_app button');
                page.evaluate(function(){
                        var evnt = document.createEvent("MouseEvents");
                        evnt.initEvent("click",true,true);
                        document.getElementById("add_new_app_link").dispatchEvent(evnt);

                });
                //page.render('step3.png');
        },

        /*
         * Step 4 - Populate and submit the First App submission vorm
         *
         * <input id="submit_button" type="submit" class="button large primary one-click-submit" name="save" value="Save" onclick="sanitizeManifestURL()">
         *
         * try looking here:
         * http://stackoverflow.com/questions/32771609/how-to-click-on-selectbox-options-using-phantomjs
         *
         */
        function(apptitle,category){
                console.log('Step 4 - save app ' + apptitle);
                page.evaluate(function(apptitle,category){
                        document.getElementById('title').value=apptitle;
                        // this works
                       document.querySelector('select').selectedIndex = 16;
                        $('select[lvl="1"]').change();
                        //document.querySelector('select[lvl="2"]').selectedIndex = 1;
                        //$('select[lvl="2"]').change();

                        //The form will be submitted, by click on the button:
                        $('#submit_button').click();
                   },apptitle,category);

                        page.render('step4.png');
//                      console.log(page.content);
        },
];

/**********END STEPS THAT FANTOM SHOULD DO***********************/

//Execute steps one by one
interval = setInterval(executeRequestsStepByStep,50);

function executeRequestsStepByStep(){
    if (loadInProgress == false && typeof steps[testindex] == "function") {
        console.log("testindex is " + testindex );
        if ( testindex == 1 ) {
                console.log( "username is " + username );
                steps[testindex](username, password);
        } else if ( testindex == 3 ) {
                steps[testindex](apptitle, category);
        } else {
            steps[testindex]();
        }
        testindex++;
    }
    if (typeof steps[testindex] != "function") {
  //We need to wait, after the steps is complete!
   clearInterval(interval);interval=0;
   setTimeout(function(){
   console.log("test complete!");
   page.render('complete.png');
   setTimeout(phantom.exit,2000)
   },3000);

    }
}

/**
 * These listeners are very important in order to phantom work properly.
 * Using these listeners, we control loadInProgress marker which controls, weather a page is fully loaded.
 * Without this, we will get content of the page, even a page is not fully loaded.
 */
page.onLoadStarted = function() {
    loadInProgress = true;
    console.log('Loading started');
};
page.onLoadFinished = function() {
    loadInProgress = false;
    console.log('Loading finished');
};
page.onConsoleMessage = function(msg) {
    console.log(msg);
};

【讨论】:

  • 啊...我知道为什么脚本挂了。但似乎按钮点击没有发生。
  • Before |也许,需要硬填充模式。 Like this
  • 这并不容易
  • 硬填充模式?谢谢!我会好好看看你发布的“喜欢这个”链接。
  • 只有Step 4 稍作修改(答案的最后编辑)。
猜你喜欢
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 2012-08-17
  • 2019-01-11
  • 2014-10-06
  • 1970-01-01
  • 2015-12-03
相关资源
最近更新 更多