LoginSignup
53

More than 5 years have passed since last update.

phpでウェブスクレイピング

Last updated at Posted at 2017-12-24

概要

・phpを用いて、食べログから自分の情報を取得する方法をまとめる。
・ゴール:食べログから必要な情報(タイトル、評価、画像パス)を取得し、csvファイルにまとめる。

流れ

1. h3の情報を取得

<?php
  // phpQueryの読み込み
  require_once("./phpQuery-onefile.php");

  // 取得したいwebサイトを読み込む
  $html = file_get_contents("対象のURL");

  // 見出し要素を取得&表示
  echo phpQuery::newDocument($html)->find("h1")->text();
?>

(参考) 【php】webサイトから、欲しい情報を3行で取得する方法

2. csvファイルに書き出し

// ファイルを開く。"a"は書き出し用として開くパラメータ。
$file = fopen("data.csv", "a");

$contents = phpQuery::newDocument($html)->find("h3")->text();

// データを1行書き込む
fputs($file, $contents."\n");

(参考)
fopen
ファイルに1行書き込む(出力) [fputs]

3. 取得した要素を一つづつ配列に格納して、一つづつファイルに書き出す

// 取得する要素の数を取得
$title_num = count(phpQuery::newDocument($html)->find("h3")->find(".rvw-item__rst-name"));

// 一つづつ配列に格納
for($i=0;$i<$title_num;$i++){
    $title[] = phpQuery::newDocument($html)->find("h3")->find(".rvw-item__rst-name:eq($i)")->text();
}

// 一つづつファイルに書き出す
foreach($title as $title_element){
    fputs($file, $title_element."\n");
}

4. 値段情報と画像情報を取得+foreachからfor文に書き換えて情報取得と書き込みを一度に行う

for($i=0;$i<$title_num;$i++){
    $title[] = phpQuery::newDocument($html)->find("h3")->find(".rvw-item__rst-name:eq($i)")->text();
    $price[] = phpQuery::newDocument($html)->find(".c-rating__val:eq($i)")->text();
    $image[] = phpQuery::newDocument($html)->find(".rvw-photo__list:eq($i)")->find('img:eq(0)')->attr('src');
    fputs($file, $title[$i].", ".$price[$i].", ".$image[$i]."\n");
}

5. リクエスト毎に1〜3秒の時間を空ける

sleep(3);

(参考)
Webスクレイピングの注意事項一覧
日本で人気のサイトを取得するスクリプトを書いた

(エラー改修) 別のページにリクエスト出しているのに、書き出される情報が同じ

・原因:$title[]$image[]に同じ情報が入っていたこと。
・解決策:$title[$p][$i]のように2次元配列に切り替える。

for($p=1;$p<5;$p++){
      $html = file_get_contents("取得したいURL");
        $title_num = count(phpQuery::newDocument($html)->find("h3")->find(".rvw-item__rst-name"));
        for($i=0;$i<$title_num;$i++){
            $title[$p][$i] = phpQuery::newDocument($html)->find("h3")->find(".rvw-item__rst-name:eq($i)")->text();
            $price[$p][$i] = phpQuery::newDocument($html)->find(".c-rating__val:eq($i)")->text();
            fputs($file, $title[$p][$i].", ".$price[$p][$i]."\n");
        }
        sleep(3);
    }

(参考) PHP 配列 連想配列 foreach 二次元配列

全てのコード

<?php
  require_once("./phpQuery-onefile.php");
    $file = fopen("data.csv", "w");

    for($p=1;$p<5;$p++){
      $html = file_get_contents("取得したいURL");
        $title_num = count(phpQuery::newDocument($html)->find("h3")->find(".rvw-item__rst-name"));
        for($i=0;$i<$title_num;$i++){
            $title[$p][$i] = phpQuery::newDocument($html)->find("h3")->find(".rvw-item__rst-name:eq($i)")->text();
            $price[$p][$i] = phpQuery::newDocument($html)->find(".c-rating__val:eq($i)")->text();
            fputs($file, $title[$p][$i].", ".$price[$p][$i]."\n");
        }
        sleep(3);
    }

    fclose($file);
?>

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53