質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

2042閲覧

【PHP】phamtomJsを用いてもjavascript実行後のhtmlが取得できない

退会済みユーザー

退会済みユーザー

総合スコア0

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2017/11/21 01:24

編集2017/11/27 07:41

###わからないこと
いつもお世話になっております。
下記のサイトの事業所一覧ページのスクレイピングを行いたくphamtomjsを使用しています。

http://www.kaigokensaku.mhlw.go.jp/01/index.php?action_kouhyou_pref_search_list_list=true&PrefCd=01&OriPrefCd=01&method=pager&p_sort_name=47&p_order_name=1&p_count=5&p_offset=0iframe=1

案件一覧の箇所がiframe内にあり、javascript実行後に表示されています。したがってphamtomjsにてjavascript実行後のhtmlを取得しようとしているのですが、うまくいっておりません。
何が誤っているのでしょうか?
またはほかの手段を考えるべきでしょうか?

####コード

     // PhantomJs $client = PClient::getInstance(); $client->getEngine()->setPath('vendor\bin\phantomjs.exe'); $projectListUrl = 'http://www.kaigokensaku.mhlw.go.jp/01/index.php?action_kouhyou_pref_search_list_list=true&PrefCd=01&OriPrefCd=01&method=pager&p_sort_name=47&p_order_name=1&p_count=5&p_offset=0iframe=1'; $client->isLazy(); $request = $client->getMessageFactory()->createRequest(); $request->setTimeout(5000); $request->setMethod('GET'); $request->setUrl($projectListUrl); $response = $client->getMessageFactory()->createResponse(); // Send the request $client->send($request, $response); if($response->getStatus() === 200) { // Dump the requested page content $conte = $response->getContent(); } // xmlへの変換 @$dom->loadHTML($conte); $xml = simplexml_import_dom($dom);

###追記 11/25
下記のようにコードを変更し、phantomjs.exeでcrawler.jsを実行し、実行結果をkaigokensaku.blade.phpに書き込む処理を行い、iframe内も取得しようとしておりますがうまく言っておりません。
原因はどこにあるのでしょうか。

php

1use JonnyW\PhantomJs\Client as PClient; 2 3 4$page = 5; 5// PhantomJs 6$client = PClient::getInstance(); 7 8 9 10for($i = 1; $i <= 47; $i++) { 11 $request = $client->getMessageFactory()->createRequest(); 12 if(strlen($i) === 1){ 13 $prefId = '0'.$i; 14 } else { 15 $prefId = $i; 16 } 17 18 $pNum = $page - 5; 19 $projectListUrl = 'http://www.kaigokensaku.mhlw.go.jp/13/index.php?action_kouhyou_pref_search_list_list=true&PrefCd=13&OriPrefCd=13&method=pager&p_sort_name=47&p_order_name=1&p_count='.$page.'&p_offset='.$pNum; 20 $client->isLazy(); rendering 21 $request = $client->getMessageFactory()->createRequest(); 22 $request->setTimeout(20000); 23 $cli = exec('C:\X_DRIVE\asp\home\laravel\vendor\bin\phantomjs.exe C:\X_DRIVE\asp\home\laravel\public\js\crawler.js '.$projectListUrl); 24 var_dump($cli);dd(); 25}

javascript

1console.log('Hello, world!'); 2var page = require('webpage').create(); 3var fs = require('fs'); 4page.open('http://www.kaigokensaku.mhlw.go.jp/13/index.php?action_kouhyou_pref_search_list_list=true&PrefCd=13', function(status) { 5if (status === 'success') { 6// HTML を書き出し 7var html = page.evaluate(function() { 8return document.getElementsByClassName('main')[0].innerHTML; 9}); 10fs.write('resources\kaigokensaku.blade.php', html, 'w'); 11} 12// exit しないと終了しない 13phantom.exit(); 14}); 15

###追記 11/27①
11/25の追記のコードの原因ですが、setTimeoutができていないことが原因と考えています。
ただ、なぜsetTimeoutできていないのかがわかっておりません。

###追記 11/27②
次のようにjsファイルのコードを変更した結果setTimeoutはじっこうされましたが、iframe内のコードは取得できませんでした。

console.log('Hello, world!'); var page = require('webpage').create(); var fs = require('fs'); page.open('http://www.kaigokensaku.mhlw.go.jp/13/index.php?action_kouhyou_pref_search_list_list=true&PrefCd=13', function(status) { window.setTimeout(function(){ if (status === 'success') { // HTML を書き出し var html = page.evaluate(function() { return document.getElementsByClassName('main')[0].innerHTML; }); fs.write('resources\kaigokensaku.blade.php', html, 'w'); } // exit しないと終了しない phantom.exit(); }, 20000); });

##追記③
jsファイルを下記のように修正することでiframe内のhtmlを取得できるようになりましたので報告いたします。

javascript

1console.log('Hello, world!'); 2var page = require('webpage').create(); 3var fs = require('fs'); 4page.open('http://www.kaigokensaku.mhlw.go.jp/13/index.php?action_kouhyou_pref_search_list_list=true&PrefCd=13', function(status) { 5 if (status === 'success') { 6 page.switchToFrame(0); 7 // HTML を書き出し 8 var html = page.evaluate(function() { 9 return document.getElementsByClassName('contents')[0].innerHTML; 10 }); 11 fs.write('resources\kaigokensaku.blade.php', html, 'w'); 12 } 13 // exit しないと終了しない 14 phantom.exit(); 15}); 16

settimeoutは不必要で「page.switchToFrame(0);」を記載することで出力できました。
ご協力ありがとうございました。

何卒よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ちゃんと対象サイトのコードを見てないので何をやってるのかよく分かりませんが、ajaxでの検索結果取得に時間がかかっているようです。
iframeの中で特定の要素(footerなど)が表示されるまで待ちましょう。

https://github.com/ariya/phantomjs/blob/master/examples/waitfor.js

面倒だったらsetTimeoutで強制的に20秒くらい待てばok。
私もよくやります。

setTimeout(function(){ //やりたい処理 }, 20000)

投稿2017/11/22 07:13

ooeok

総合スコア469

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/23 02:27

ooeok様 ご回答ありがとうございます。 確認なのですが、質問欄にあるコードですと、 $projectListUrlの定義位置から、simplexml_import_domまでをsetTimeoutでくくる感じでしょうか?
退会済みユーザー

退会済みユーザー

2017/11/23 02:27

上記で試みた結果、何も出力されなくなりまして・・・
ooeok

2017/11/23 09:01

まずyouthKさんのコードはphantomjsではなく、php-phantomjsですよね。 それからPClientといった別名を使う場合はuseから載せるべきです。 下の質問を見るまで理解できませんでした。 https://teratail.com/questions/100717 誰もがyouthKさんの以前の質問を追っているわけではないのですから、1つの質問内でできるだけ必要な情報を載せるようにして下さい。 次に待ち時間ですが、あらためてwaitを入れる必要ありませんでした。 isLazyが設定されているので、 > $request->setTimeout(20000); とすればokです。 で、本題。 getContentではiframe内のhtmlを取得できません。 xmlに変換する前に、phantomjsでiframe内のbodyタグを捜査するといった処理をする必要があります。 しかしphp-phantomjsでは細かい処理が難しいです(がんばればできるのかも?)。 php-phantomjsを使わず、phantomjsをそのまま使うことをオススメします。
退会済みユーザー

退会済みユーザー

2017/11/23 09:22

お手間をとらせてしまい申し訳ございませんでした。 どのライブラリを使っているかなど、明記するようにいたします。 php版では取得できないのですね。。。 使うべきphantomjsはooeok様が最初に回答してくださったgitのものでしょうか?
ooeok

2017/11/23 09:32

php-phantomjsはphp版のphantomjsではなく、単にphantomjsをphpから使えるようにしただけです。 なので、vendor\bin\phantomjs.exeでokです。
退会済みユーザー

退会済みユーザー

2017/11/23 09:47

申し訳ございません。理解しかねております。 別途「.js」ファイルを作成し、そこにiframe内のbodyを出力するような処理を書いて、phantomjs.exeを実行して「.js」ファイルで取得した中身をPHP側にもってくるということでしょうか?
ooeok

2017/11/23 10:47

そうです。 execで実現できますよ。
退会済みユーザー

退会済みユーザー

2017/11/25 11:35

質問に追記させていただきました。 よろしければご確認をお願い致します。
ooeok

2017/11/27 07:31

iframeにswitchしないとダメなんじゃないでしょうか。 このへん調べればなんとかなると思いますよ。 switchToParentFrame() switchToFrame()
退会済みユーザー

退会済みユーザー

2017/11/27 07:38

ご回答ありがとうございます 解決させることができましたので、質問欄「追記③」に解決方法を記載いたします。 ご助力ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問