javascript 如何从 CasperJS 访问 iframe?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12150194/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 15:26:59  来源:igfitidea点击:

How do I access an iframe from CasperJS?

javascriptiframewebkitphantomjscasperjs

提问by Jim Paris

I have a webpage with an iframe. I'd like to access the contents of the iframe using CasperJS. In particular, I need to click buttons and fill a form. How can I do that?

我有一个带有 iframe 的网页。我想使用CasperJS访问 iframe 的内容。特别是,我需要单击按钮并填写表格。我怎样才能做到这一点?

The main webpage is main.html:

主网页是 main.html

<html><body>
<a id='main-a' href="javascript:console.log('pressed main-a');">main-a</a>
<iframe src="iframe.html"></iframe>
<a id='main-b' href="javascript:console.log('pressed main-b');">main-b</a>
</body></html>

The iframe is:

iframe 是:

<html><body>
<a id='iframe-c' href="javascript:console.log('pressed iframe-c');">iframe-c</a>
</body></html>

My na?ve approach:

我天真的方法:

var casper = require('casper').create({
    verbose: true,
    logLevel: "debug"
});

casper.start("http://jim.sh/~jim/tmp/casper/main.html", function() {
    this.click('a#main-a');
    this.click('a#main-b');
    this.click('a#iframe-c');
});

casper.run(function() {
    this.exit();
});

Doesn't work, of course, because the a#iframe-cselector isn't valid in the main frame:

当然不起作用,因为a#iframe-c选择器在主框架中无效:

[info] [phantom] Starting...
[info] [phantom] Running suite: 2 steps
[debug] [phantom] opening url: http://jim.sh/~jim/tmp/casper/main.html, HTTP GET
[debug] [phantom] Navigation requested: url=http://jim.sh/~jim/tmp/casper/main.html, type=Other, lock=true, isMainFrame=true
[debug] [phantom] url changed to "http://jim.sh/~jim/tmp/casper/main.html"
[debug] [phantom] Navigation requested: url=http://jim.sh/~jim/tmp/casper/iframe.html, type=Other, lock=true, isMainFrame=false
[debug] [phantom] Successfully injected Casper client-side utilities
[info] [phantom] Step 2/2 http://jim.sh/~jim/tmp/casper/main.html (HTTP 200)
[debug] [phantom] Mouse event 'click' on selector: a#main-a
[info] [remote] pressed main-a
[debug] [phantom] Mouse event 'click' on selector: a#main-b
[info] [remote] pressed main-b
[debug] [phantom] Mouse event 'click' on selector: a#iframe-c
FAIL CasperError: Cannot dispatch click event on nonexistent selector: a#iframe-c
#    type: uncaughtError
#    error: "CasperError: Cannot dispatch click event on nonexistent selector: a#iframe-c"
CasperError: Cannot dispatch click event on nonexistent selector: a#iframe-c    
  /tmp:901 in mouseEvent
  /tmp:365 in click
  /tmp/test.js:9
  /tmp:1103 in runStep
  /tmp:324 in checkStep

Is there any way to make this work? A hack that involves poking into phantomjs directly would be fine, but I don't know what to do there.

有什么办法可以使这项工作?涉及直接进入 phantomjs 的 hack 会很好,但我不知道在那里做什么。

I'm using CasperJS version 1.0.0-RC1 and phantomjs version 1.6.0.

我使用的是 CasperJS 版本 1.0.0-RC1 和 phantomjs 版本 1.6.0。

回答by Jim Paris

Spent forever looking for this, and of course I found the answer minutes after posting the question.

一直在寻找这个,当然我在发布问题几分钟后找到了答案。

I can use the new frame switching commands added to phantomjs in this commit. Specifically, the this.page.switchToChildFrame(0)and this.page.switchToParentFrame()functions. It appears undocumented, and it also seems that the methods have been changedfor upcoming releases, but it does work:

我可以在此提交中使用添加到 phantomjs 的新帧切换命令。具体来说,this.page.switchToChildFrame(0)this.page.switchToParentFrame()功能。它似乎没有记录,而且似乎为即将发布的版本更改了方法,但它确实有效:

var casper = require('casper').create({
    verbose: true,
    logLevel: "debug"
});

casper.start("http://jim.sh/~jim/tmp/casper/main.html", function() {
    this.click('a#main-a');
    this.click('a#main-b');
    this.page.switchToChildFrame(0);
    this.click('a#iframe-c');
    this.page.switchToParentFrame();
});

casper.run(function() {
    this.exit();
});

回答by olleolleolle

From 1.0 you can use withFrame

从 1.0 开始,您可以使用withFrame

  casper.open("http://www.example.com/page.html", function() {
    casper.withFrame('flashHolder', function() {
      this.test.assertSelectorExists('#the-flash-thing', 'Should show Flash');
    });
  });

回答by Turcu Vlad

As a matter of fact you'll have to use the new --web-security=nofeature provided by Phantomjs 1.5in order to be able to access those iFramesand their contents.

事实上,您必须使用--web-security=no提供的新功能Phantomjs 1.5才能访问这些 iFrames内容及其内容。

回答by Siddhartha Dimania

Suppose we have different frames(frame1 and frame2) and we have to access different elements(like click or check if div tag exits or not) of those frames.

假设我们有不同的框架(frame1 和 frame2),我们必须访问这些框架的不同元素(例如单击或检查 div 标签是否存在)。

casper.withFrame('frame1', function() {
    var file = '//*[@id="profile_file"]';
    casper.thenClick(x(file));
});

casper.withFrame('frame2', function() {
  casper.then(function () {
     casper.waitForSelector('#pageDIV',
            function pass() {
                console.log("pass");
            },
            function fail(){
                console.log("fail");
            }
      );
   });
});

回答by Bla...

You can do something like this:

你可以这样做:

casper.start("url here...", function() { 
    this.withFrame(0, function() {
        this.evaluate(function() {
            document.querySelector('img#btn_start').click();
        })
    })
});

You can replace the zero with the name of the iframe.

您可以用 iframe 的名称替换零。