Javascript 如何从CasperJS访问iframe?

Javascript 如何从CasperJS访问iframe?,javascript,iframe,webkit,phantomjs,casperjs,Javascript,Iframe,Webkit,Phantomjs,Casperjs,我有一个带有iframe的网页。我想使用访问iframe的内容。特别是,我需要单击按钮并填写表单。我该怎么做 主要网页是 : 当然不起作用,因为a 35; 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 [d

我有一个带有iframe的网页。我想使用访问iframe的内容。特别是,我需要单击按钮并填写表单。我该怎么做

主要网页是 :

当然不起作用,因为
a 35; 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
有什么办法可以让这一切顺利进行吗?直接戳入phantomjs的黑客可以,但我不知道该怎么做


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

事实上,您必须使用新的
--web安全=否

Phantomjs 1.5提供的功能,以便能够访问这些

iFrames
及其内容。

花了很长时间寻找这个,当然我在发布问题几分钟后就找到了答案

我可以使用中添加到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();
});
从1.0开始,您可以使用


假设我们有不同的帧(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");
            }
      );
   });
});

您可以这样做:

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

您可以将0替换为iframe的名称。

实际上并不相关——这个示例是同一个域iframe,跨域安全性不是我的问题。查看我自己的答案,了解什么有效(
--web security=no
在那里仍然不是必需的)。Jim,您是否知道在切换后是否可以使用这个.test.assertVisible(“#someleminsideiframe”)?对我来说似乎很恶心,但这个。点击(…)有效。我没有,对不起。我不确定是否可以用其他方法测试可见性,但这种方法对框架不起作用。你看到@OlleOlle的答案了吗?withFrame是一个有文档记录的方法。是的,我有<当我问这个问题或接受这个答案时,code>withFrame
不存在,但从现在起,它似乎是正确的使用方法。如何处理具有动态名称的框架?我不能依赖框架索引(例如0或1),因为像twitter这样的社会服务(通过addthis)经常在后台加载自己的iFrame。你可以使用框架索引而不是框架名称-
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();
});
  casper.open("http://www.example.com/page.html", function() {
    casper.withFrame('flashHolder', function() {
      this.test.assertSelectorExists('#the-flash-thing', 'Should show Flash');
    });
  });
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");
            }
      );
   });
});
casper.start("url here...", function() { 
    this.withFrame(0, function() {
        this.evaluate(function() {
            document.querySelector('img#btn_start').click();
        })
    })
});