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

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

<h2>流れ</h2>
<h3>1. h3の情報を取得</h3>
```php
<?php
  // phpQueryの読み込み
  require_once("./phpQuery-onefile.php");

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

  // 見出し要素を取得&表示
  echo phpQuery::newDocument($html)->find("h1")->text();
?>
```
（参考）<a href="https://qiita.com/dia/items/3cf963fa89b08b87e8ef"> 【php】webサイトから、欲しい情報を3行で取得する方法</a>
 
<h3>2. csvファイルに書き出し</h3>
```php
// ファイルを開く。"a"は書き出し用として開くパラメータ。
$file = fopen("data.csv", "a");

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

// データを1行書き込む
fputs($file, $contents."\n");
```
（参考） 
・<a href="http://php.net/manual/ja/function.fopen.php">fopen</a>
・<a href="http://pg-memo.sakura.ne.jp/php_file_003_001.html">ファイルに1行書き込む(出力) [fputs]</a>


<h3>3. 取得した要素を一つづつ配列に格納して、一つづつファイルに書き出す</h3>
```php
// 取得する要素の数を取得
$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");
}
```

<h3>4. 値段情報と画像情報を取得＋foreachからfor文に書き換えて情報取得と書き込みを一度に行う</h3>
```php
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");
}
```

<h3>5. リクエスト毎に1〜3秒の時間を空ける</h3>
```php
sleep(3);
```
（参考）
・<a href="https://qiita.com/nezuq/items/c5e827e1827e7cb29011">Webスクレイピングの注意事項一覧</a>
・<a href="https://qiita.com/saxsir/items/a85ee3c5fb9d3bd76dde">日本で人気のサイトを取得するスクリプトを書いた</a>

<h3>(エラー改修) 別のページにリクエスト出しているのに、書き出される情報が同じ</h3>
・原因：```$title[]```と```$image[]```に同じ情報が入っていたこと。
・解決策：```$title[$p][$i]```のように2次元配列に切り替える。

```php
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);
	}
```
（参考） <a href="https://qiita.com/icelandnono/items/eb150f8b254e4daebed0">PHP 配列 連想配列 foreach 二次元配列</a>

<h2>全てのコード</h2>
```php
<?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);
?>

```