IframeのあるWebページがあります。 CasperJS を使用してiframeのコンテンツにアクセスしたいと思います。特に、ボタンをクリックしてフォームに入力する必要があります。どうやってやるの?
メインWebページは 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>
Iframeは次のとおりです。
<html><body>
<a id='iframe-c' href="javascript:console.log('pressed iframe-c');">iframe-c</a>
</body></html>
私の素朴なアプローチ:
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();
});
もちろん機能しません。なぜなら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
これを機能させる方法はありますか? phantomjsに直接突っ込むハックは問題ありませんが、そこでどうすればよいかわかりません。
CasperJSバージョン1.0.0-RC1とphantomjsバージョン1.6.0を使用しています。
これを探して永遠に費やし、もちろん質問を投稿してから数分で回答が見つかりました。
this commit でphantomjsに追加された新しいフレーム切り替えコマンドを使用できます。具体的には、this.page.switchToChildFrame(0)
およびthis.page.switchToParentFrame()
関数です。これは文書化されていないようであり、メソッドは次のリリースでは changed になっているようですが、機能します。
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から withFrame を使用できます
casper.open("http://www.example.com/page.html", function() {
casper.withFrame('flashHolder', function() {
this.test.assertSelectorExists('#the-flash-thing', 'Should show Flash');
});
});
実際、iFrames
とそのコンテンツにアクセスできるようにするには、--web-security=no
が提供する新しいPhantomjs 1.5
機能を使用する必要があります。
異なるフレーム(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();
})
})
});
ゼロはiframeの名前に置き換えることができます。