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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

PHP

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

Q&A

解決済

3回答

762閲覧

PHP(phpQueryを使用)でwebスクレイピングを行いjsonデータを取得したい

urasamaru

総合スコア16

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

PHP

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

0グッド

0クリップ

投稿2020/01/13 06:07

編集2020/01/13 10:16

当方PHP初心者です。
PHP(phpQueryを使用)でwebスクレイピングを行いたいです。
対象ページに該当のソースコードのような構文でjsonデータが収まってるのですが、このjsonの取得方法が分かりません。

該当のソースコード

<script id="js-live-data" data-json={"ここにjsonデータが入ってます"}></script>

試したこと

<?php require_once("./phpQuery-onefile.php"); $html = file_get_contents("対象URL"); $dom = phpQuery::newDocument($html); echo $dom["#js-live-data"]->text(); ?>

などで試しましたがうまくいきません。

ご教授の程、宜しくお願い致します。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/01/13 06:13

>find("script id=")->text(); >などで試しましたがうまくいきません。 どうしてこれで取れると思ったのか、ちょっと説明してみてくれねぇかな? 流石に呆れたぞ。
urasamaru

2020/01/13 06:19

冒頭に書いた通り初心者なんですよ 申し訳ありません。
FKM

2020/01/13 06:58

SQLの勉強からやり直した方がよさそうですね。プログラムやライブラリのクエリ処理ってのは結局そこから枝分かれしている技術に過ぎませんので。
urasamaru

2020/01/13 07:53

ちなみにEXCEL VBAで同じことをしていますが正常に取得出来てます。 なのでPHPの書き方が分からないだけの問題だと思ってます。
FKM

2020/01/13 08:27 編集

EXCELVBAで経験がある(一定の言語リテラシーがある)とのことなので、解説は少なめにしてます。 PHPQueryはWEBページのタグやクラス名を探索してデータを取得するWEBスクレイピング目的の技術なので、用途が違います。
m.ts10806

2020/01/13 08:34

ひとまず質問に「初心者アイコン」つけましょう。
urasamaru

2020/01/13 08:47

初心者アイコン付けました。 すみません、当サイト初めてなもので。
m.ts10806

2020/01/13 08:50

ついでのコードのマークダウン対応も覚えておきましょう。 https://teratail.com/help#about-markdown それだけで回答者側の「質問を見る負担」「現象の再現確認の負担」がぐっと減ります。
urasamaru

2020/01/13 08:59

ありがとうございます。 サイトの仕様も理解して次回から質問するようにします。
退会済みユーザー

退会済みユーザー

2020/01/13 08:59

正常なタグじゃないので取れません
urasamaru

2020/01/13 09:08

<script id="js-live-data" data-json={"ここにjsonデータが入ってます"}</script> これが正常ではないと言う事でしょうか? 記載済みですが、EXCELVBAでは取得出来てるのですが。。
m.ts10806

2020/01/13 09:12 編集

<script はどこで閉じてますか? </script>という意味ではなく。開始タグの終了の閉じ位置ですね。
urasamaru

2020/01/13 09:14

すみません、記載ミスでした。 <script id="js-live-data" data-json={"ここにjsonデータが入ってます"}></script> です。
m.ts10806

2020/01/13 09:14

はい。念のため質問本文も更新しておいてください。 全ての人がこちらのコメントを読むわけではありません。 (ついでにコードのマークダウン対応もお願いしますね)
退会済みユーザー

退会済みユーザー

2020/01/13 09:57

うまくいかない、のは、file_get_contents()は動作していて取得できているけど、その後のことがよくないってこと? var_dump($html); とか var_dump($dom); とかやってデータは入っているのかな。 一旦、file_get_contents() で取得したデータをファイルに書き出して、テストは書き出したファイルから読み込むようにすれば先方のサーバーに負担をかけずにテストできるよ。そのうえで、書き出したファイルをエディタで読み込んで該当箇所が含まれるかをチェックするのが第一歩。(Chromeでソースを見るなどすると、jsでレンダリングした後のコードを観させられる場合があってな。)
urasamaru

2020/01/13 10:10

>うまくいかない、のは、file_get_contents()は動作していて取得できているけど、その後のことがよくないってこと? はい。 最後を単純に、echo $dom["title"]->text(); にするとタイトルは表示される状態です。
m.ts10806

2020/01/13 10:13

あと良く見たらコード1列目に全角スペース入ってますね。 実際のコードに入ってないのでしたらそこは調整いただきたく。
退会済みユーザー

退会済みユーザー

2020/01/13 10:15

file_get_contents() したらすぐ file_put_contents() とかでファイルに保存して、その該当する script id=の文字列が含まれるかどうか。
urasamaru

2020/01/13 10:23

>m.ts10806さん  修正しました。 >m6uさん  file_put_contents()を使ってテキストファイルに保存し中を確認しましたが、該当のscript id="js-live-data"はちゃんと出力されている事を確認しました。
guest

回答3

0

おそらく質問者さんが使われているのは Google Code Archiveのものと思いますが、最終更新が2009年と古いため、packagistに載せられているものを元に検証してみました( 2019-08-08 19:13 UTC)。

ですのであくまで参考までとしてください。

分かったこと。
idやclassにハイフンあったら取れませんでした。
アンダースコアは取れます。

HTML5上は空白文字を除く全ての文字が利用できる(出典)ので、これはphpQueryの仕様なんじゃないかなと(未調査)

で、一応下記のようなコードで、id名をハイフンからアンダースコアに変更したらタグの情報を取得しました。

html

1<script id="js_live_data" data-json="ここにjsonデータが入ってます"></script>

php

1require_once "vendor/autoload.php"; 2use PhpQuery\PhpQuery; 3$html = file_get_contents('test.html'); 4$pq=new PhpQuery; 5$pq->load_str($html); 6 7var_dump($pq->query('#js_live_data')[0]);

出力結果は下記

object(DOMElement)#5 (18) { ["tagName"]=> string(6) "script" ["schemaTypeInfo"]=> NULL ["nodeName"]=> string(6) "script" ["nodeValue"]=> string(0) "" ["nodeType"]=> int(1) ["parentNode"]=> string(22) "(object value omitted)" ["childNodes"]=> string(22) "(object value omitted)" ["firstChild"]=> NULL ["lastChild"]=> NULL ["previousSibling"]=> string(22) "(object value omitted)" ["nextSibling"]=> string(22) "(object value omitted)" ["attributes"]=> string(22) "(object value omitted)" ["ownerDocument"]=> string(22) "(object value omitted)" ["namespaceURI"]=> NULL ["prefix"]=> string(0) "" ["localName"]=> string(6) "script" ["baseURI"]=> NULL ["textContent"]=> string(0) "" }

attributesが属性なので

php

1var_dump($pq->query('#js_live_data')[0]->attributes);
object(DOMNamedNodeMap)#6 (1) { ["length"]=> int(2) }

php

1var_dump($pq->query('#js_live_data')[0]->attributes[1]);
object(DOMAttr)#7 (21) { ["name"]=> string(9) "data-json" ["specified"]=> bool(true) ["value"]=> string(76) "ここにjsonデータが入ってます" ["ownerElement"]=> string(22) "(object value omitted)" ["schemaTypeInfo"]=> NULL ["nodeName"]=> string(9) "data-json" ["nodeValue"]=> string(76) "ここにjsonデータが入ってます" ["nodeType"]=> int(2) ["parentNode"]=> string(22) "(object value omitted)" ["childNodes"]=> string(22) "(object value omitted)" ["firstChild"]=> string(22) "(object value omitted)" ["lastChild"]=> string(22) "(object value omitted)" ["previousSibling"]=> string(22) "(object value omitted)" ["nextSibling"]=> NULL ["attributes"]=> NULL ["ownerDocument"]=> string(22) "(object value omitted)" ["namespaceURI"]=> NULL ["prefix"]=> string(0) "" ["localName"]=> string(9) "data-json" ["baseURI"]=> NULL ["textContent"]=> string(76) "ここにjsonデータが入ってます" }

php

1var_dump($pq->query('#js_live_data')[0]->attributes[1]->textContent);
string(76) "ここにjsonデータが入ってます"

正しくたどれば「おそらく」取得できるんじゃないかなとは思います。

投稿2020/01/13 11:43

m.ts10806

総合スコア80765

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

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

m.ts10806

2020/01/13 11:44

やっている間に解決してしまわれたか。
guest

0

PHPQueryのことは一旦忘れて、こっちを参考にしてください。json_decode関数という便利な関数があるので、これでデータ化します。その際、文字化け対策を忘れずに。

PHPでJSONデータの取得の仕方

投稿2020/01/13 08:11

FKM

総合スコア3608

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

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

urasamaru

2020/01/13 08:15

ありがとうございます。 json_decode関数についても試しつつやってみたいと思います。
guest

0

自己解決

echo $dom["#js-live-data"]->attr("data-json");
で取得出来ました。

手助け頂いた皆様、ありがとうございました。

投稿2020/01/13 11:22

urasamaru

総合スコア16

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

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

m.ts10806

2020/01/13 11:48

attr("data-json")がいけるなら data("json") がいけそうですし、 このほうがよりそれっぽい書き方になりますが、いかがでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問