如何:使用CasperJS在iFrame中选择单选按钮?

时间:2016-11-06 15:01:40

标签: javascript iframe javascript-events radio-button casperjs

我是JavaScript的新手,是CasperJS的新手,等等。但是,我观看了几个YouTube视频,并使用CasperJS完成了一些示例。从这个优势我认为我对基础知识有了很好的把握,并为我的第一个项目做好了准备,我目前正在坚持这个项目。 如何点击单选按钮?

我不知道这是我正在使用的网站的独特之处,还是我的理解中的一些额外漏洞,但我尝试的任何内容似乎都无效。我非常感谢任何投入;我一直在黑暗中磕磕绊绊......

由于我是新手,我会提供详细信息,因为有些事情我做错了,或者应该考虑做等等谢谢!

问题

当我打开网站网址时:http://www.ddbst.com/unifacga.html我受到以下四个选项的欢迎: enter image description here 所以我右键单击控件并使用DevTools获取元素的信息:

<input name="selection" value="Upload" id="ID1" type="radio" onclick="this.form.submit()">
<input name="selection" value="MolinspirationJME" id="ID2" type="radio" onclick="this.form.submit()">
<input name="selection" value="Insert" id="ID3" type="radio" onclick="this.form.submit()">
enter code here
<input name="selection" value="DDBSearch" id="ID4" type="radio" checked="checked" onclick="this.form.submit()">

我对 DDBSearch 感兴趣(选项号4)。我还没有用单选按钮做一个例子,我原本以为我可以做一些像value = true,但后来我看到该值实际上是一个文本字符串,所以我点击按钮查看它的活动状态:

<input name="selection" value="DDBSearch" id="ID4" type="radio" checked="checked" onclick="this.form.submit()">

所以我知道我需要以某种方式激活属性已检查,但我无法通过XPath,ID,Name等执行此操作。不知道我试图报告的问题是什么使用网络上的其他示例提供更多错误信息。

Casper构造函数选项

我按如下方式设置了我的casper对象:

var casper = require("casper").create({
    logLevel:"debug",
    verbose:true,               // log messages will be printed out to the console
    pageSettings:{              // the WebPage instance used by Casper will use these settings.
        loadImages: false,      
        loadPlugins: false,
        webSecurityEnabled: false
    },
        onDie: function(){
            console.log("Script complete.");
        },
        // Display message every time any page successfully initializes:
        onPageInitialized: function(){
            console.log("\rPage initialized.\r");
        },
    waitTimeout: 10000,
    stepTimeout: 10000,
        onWaitTimeout: function(){ // invoked when you are waiting for an element to be visible, e.g. after clicking a button, and waitTimeout has been exceeded.
            this.echo("** Wait-TimeOut **");
        },
        onStepTimeout: function(){ // NOT REALLY SURE WHAT THIS IS USED FOR ???
            this.echo("** Step-TimeOut **");
        }
});

尝试使用类似的代码来捕获其他错误信息。

casper.on('remote.message', log);
casper.on('error', logError);
casper.on('complete.error', logError);
casper.on('page.error', logError);

需要其他功能:

function log(msg){
    console.log("\r");
    console.log('Remote msg>: ', msg);
    console.log("----------------------------------------------------","\r");
}

function logError(msg,traceback){
    console.log("\r");
    console.log(msg);
    console.log(traceback);
    console.log("----------------------------------------------------","\r");
}

我不确定从哪里得到它,或者它是如何工作的,但它看起来应该报告其他错误信息,所以我去了。

验证页面结构

我在某处读到你应该首先验证页面结构,所以我把它建立在 opeform 表格上,其中包含了无线电选项。此时我还注意到,我真正想要的其他输入字段(在选项4之后被选中)只是隐藏在页面上 - 不确定这是否重要?

在我看来,使用表单的隐藏元素会更容易;因此,绕过我目前拥有的无线电选项问题? (现在只是在背景中燃烧的想法..)

<form name="opeform" method="post" action="http://ddbonline.ddbst.com/OnlinePropertyEstimation/OnlineUNIFACGroupAssignmentSA.exe">
<hr>
<table border="0" style="white-space: nowrap; font-size:10pt;width: 560px; text-align: left;" cellpadding="2" cellspacing="2">
<tbody><tr><td>
<h3>Input Method</h3><input name="selection" value="Upload" id="ID1" type="radio" onclick="this.form.submit()"><b>Upload</b> a Mol- or CTC-file directly from your hard drive<br>
<input name="selection" value="MolinspirationJME" id="ID2" type="radio" onclick="this.form.submit()"><b>Molinspiration JME</b> allows to draw and edit molecules (Java required)<br>
<input name="selection" value="Insert" id="ID3" type="radio" onclick="this.form.submit()"><b>Insert</b> the content of a Molfile in a textfield<br>
<input name="selection" value="DDBSearch" id="ID4" type="radio" onclick="this.form.submit()"><b>DDB Search</b> (retrieves a structure from the chemical structure database ChemDB)</td>
</tr>
</tbody>
</table>
<input type="hidden" id="ID9" name="molstruct" value="">
</form>

所以我使用CasperJS断言系统确保表单 opeform 在继续之前就已存在:

var selector = "#unifacga";
casper.then(function(){
    console.log("\r>>> Check if the element exists.");
    console.log(">>> If the element does not exist, the test (i.e. our script) will fail, otherwise it will simply continue.\r");
    this.waitForSelector(selector,
        function pass () {
            this.capture("open.png");
            console.log("\r",">>> Element found");
            console.log("1: ",this.evaluate(function(sel){return !!document.querySelector(sel)},selector));
            console.log("2: ",this.evaluate(function(sel){return document.querySelector(sel).textContent;},selector));
            console.log(">>> Continue.","\r");
        },
        function fail () {
            this.capture("fail.png");
            this.die(">>> Did not load element... something is wrong T_T","\r");
        }
    );
});

到目前为止,一切都是玫瑰的阳光......

尝试No.1 - 通过XPATH选择无线电选项

我首先尝试使用XPath,因为这是许多示例用于单击按钮的内容:

var x = require("casper").selectXPath;
// //*[@id="ID4"] is the XPath statement.
// input type that has the attribute id as radio.
casper.thenClick(x('//*[@id="ID4"]'));
casper.wait(5000).then(function(){
    casper.capture("option_sel4.png");
});
casper.run();

我得到的错误如下: enter image description here 它表示不存在选择器,但语法看起来正确(据我所知),ID最明确地是“ID4”(如上所示,来自DevTools)。

尝试2号 - 无线电选项按ID(和名称)选择

所以我接下来尝试使用ID(和名称)来处理对象:

casper.evaluate(function(){
    document.getElementById("ID4").checked=true;
});
casper.run();

现在我得到一个不同的错误: enter image description here 所以现在我得到了一个类型错误。看起来像我使用它的getElementByID方法可能不会返回对象或什么?任何其他变体,例如getElementByName导致类似的错误......

尝试No.3 - Casper.Click

我也试过CasperJS.click:

casper.then(function() {
  this.click('input[id="ID4"][checked="checked"]');
});
casper.run();

导致另一个错误,如XPath: enter image description here

结论

我不知道如何解决这个问题。似乎我尝试选择无线电选项4的所有内容都会导致某种类型的错误;但是,我对JavaScript和CasperJS的了解还不足以解决任何问题。到目前为止,我在网上试过的其他解决方案对我来说都没有用。任何帮助都会非常有用。

1 个答案:

答案 0 :(得分:1)

使用我的功能click2iframe,不要忘记--web-security=no选项,例如./casperjs --web-security=no snap.js

function click2iframe(sel_of_the_iframe,sel_in_the_iframe){
var event=document.createEvent('MouseEvents'),element=document.querySelector(sel_of_the_iframe).contentDocument.querySelector(sel_in_the_iframe);event.initMouseEvent('click',1,1,window,1,0,0,0,0,0,0,0,0,0,null); element.dispatchEvent(event);
}
var casper = require('casper').create();
casper.start('http://www.ddbst.com/unifacga.html').wait(5000).then(function(){
this.capture('test0.png');
this.evaluate(function(click2iframe){
click2iframe('iframe[name="ircframe"]','input[id="ID4"]');
},click2iframe);
});
casper.wait(5000).then(function(){this.capture('test.png');}).wait(2000);
casper.run();

奖金示例:click3_iframe函数,如果您需要点击位于第3个iframe的元素:

<iframe id="1"><iframe id="2"><iframe id="3">
<a id="some_id" href="">some text</a>
</iframe></iframe></iframe>

function click3_iframe(sel_of_the_iframe,sel_of_the_iframe2,sel_of_the_iframe3,sel_in_the_iframe){
var event=document.createEvent('MouseEvents'),
element=document.querySelector(sel_of_the_iframe).contentDocument.querySelector(sel_of_the_iframe2).contentDocument.querySelector(sel_of_the_iframe3).contentDocument.querySelector(sel_in_the_iframe);
event.initMouseEvent('click',1,1,window,1,0,0,0,0,0,0,0,0,0,null); element.dispatchEvent(event);
}
click3_iframe("iframe#1","iframe#2","iframe#3","a#some_id");