webページをスクレイピングして更新があったところだけを表示させるには...?
解決済
回答 2
投稿
- 評価
- クリップ 0
- VIEW 3,193
前提・実現したいこと
PHPであるサイトをスクレイピングし、前回スクレイピングした時と比べて更新があった部分だけを抽出し、表示させるようなことをやろうと思ってます。スクレイピングにはPHP Simple HTML DOM Parserを使っています。
わからないところ
どうやって更新分を抽出するのかがわかりませんinclude_once('simplehtmldom_1_5/simple_html_dom.php');
$html = file_get_html( 'http://google.co.jp' );
// 指定した要素を$elem1に代入
$elem1 = $html->find('p[class="hoge"]/a')
$elem1の他に$elem2(前回スクレイピングした分)を用意し、それと$elem1比較して、更新があった部分だけを取り出そうといろいろ調べてたのですが、よくわからない&うまく行きませんでした。(array_diff()を使ったりしてみましたが..)
どのように処理すれば、更新分を抽出して表示させることができるでしょうか?
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+2
このコードの場合、$elem1 はsimple_html_domオブジェクトになっています。
foreach等でアクセスできているのは、このオブジェクトが、配列で操作できるように作られているためです。
var_export($elem1) を実行すると、この変数の内部が見られますが、実際はアクセスしている配列以外にもたくさんのデータが格納されていることが分かります。
そして深い階層になっている部分もあるため、この階層がserialize関数の許容範囲を超えているためにエラーが出ます。
で、解決方法ですが、必要なのは配列部分だけなので、
foreach( $elem1 as $data ) {
if(in_array($data, $elem2)==false){
echo $data."<br>";
}
}
// $hogeにシリアライズした$elem1を代入
$hoge = serialize($elem1);
で直接$elem1をシリアライズするのではなく
$new_arr = array();
foreach( $elem1 as $data ) {
$new_arr[] = $data;
if(in_array($data, $elem2)==false){
echo $data."<br>";
}
}
// $hogeにシリアライズした$new_arrを代入
$hoge = serialize($new_arr);
とすれば、必要な配列部分だけをシリアライズできるかと思います。投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
また順番が変わっただけでも更新と判定したいのかどうか、などに寄っても、処理方法が異なってくるかと思います。
配列に入っているデータを単純に比較するだけなら
$new_arr = array(新しい取得データの配列);
$old_arr = array(古い取得データの配列);
foreach( $new_arr as $data ) {
if (in_array($data, $old_arr)==false) echo $data."\n";
}
とすると、新しく追加されたデータだけ表示されます。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.09%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2015/10/30 20:18
また、表示されるデータに関してですが、新着更新された分のデータだけではなく、
前回読み込んで抽出した新着+今回抽出した新着
というような形で表示されていってます。
2015/10/30 20:24
エラーの内容で、serializeかunserializeのどちらかだと思いますが、unserializeの方で失敗しているなら、一度データを消すしかないかも。
2015/10/30 20:41 編集
if(in_array($data, $elem2)==false)
の行で起きてます。
一度データを消しましたが状況は変わりませんでした。
2015/10/30 23:58
$new_arr[] = $data;
のところを
$new_arr[] = (string)$data;
しないとダメかも。
$elem2がちゃんと配列になってるかどうかとか、チェックした方がいいかと思います。
配列とオブジェクトの違いなど、もう少し型を意識してコードを書いた方がいいですね。
2015/10/31 10:55
としたところ、解決しました!!
$elem2はキチンと配列になっていました。
今後、それらを意識して書くようにします。
アドバイス等ありがとうございました。大変助かりました。