Help us understand the problem. What is going on with this article?

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした