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

More than 1 year has passed since last update.

概要

・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);
?>