miya

phpQueryでWEBスクレイピングしてみた

phpQueryというjQueryのような感覚でDOM操作ができるPHP用ライブラリを使ってWEBスクレイピングしてみました。

WEBスクレイピングとは

ウィキペディアより

ウェブスクレイピング(Web scraping)とは、ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと。ウェブ・クローラー(Web crawler) あるいはウェブ・スパイダー(Web spider)とも呼ばれる。

注意点

利用規約に反していないか、サーバの負荷など注意しなければいけない点がいくつかあります。下記の記事などを参考にして問題がないか十分に注意してください。

phpQueryのダウンロード

phpQueryのダウンロードページから最新の「phpQuery-...-onefile.zip」をダウンロードします。
https://code.google.com/archive/p/phpquery/downloads

公式ブログ
phpQuery blog

WEBスクレイピングする

Tips Noteのトップページから、更新日と記事タイトルを取得し、JSON形式で出力してみたいと思います。
https://www.tam-tam.co.jp/tipsnote/

<?php
// phpQueryの読み込み
require_once("phpQuery-onefile.php");
// HTMLの取得
$doc = phpQuery::newDocumentFile("https://www.tam-tam.co.jp/tipsnote/");

foreach ($doc[".l-main"]->find(".entry-box") as $entry){
  //更新日
  $date = pq($entry)->find('time')->attr('datetime');
  //タイトル
  $h1 = pq($entry)->find('h1')->text();
  //配列に格納
  $jsonData[] = ['title' => $h1, 'date' => $date];
}

//json を出力
header(" Content-Type:application/json; charset=utf-8");
echo json_encode($jsonData, JSON_UNESCAPED_UNICODE);

下記のようなJSONデータが出力できました。

[
    {
        "date": "2016-05-18", 
        "title": "画像の書き出し作業を圧縮する Photoshopデザインのポイント"
    }, 

    ~~~~~~省略~~~~~~
]

キャッシュ化しておく

アクセスする度にスクレイピングして情報を取得しているとサーバに負荷がかかるので、一定の期間はキャッシュさせて負荷を減らす処理を追加しました。

出力したJSONデータをファイルに保存して、キャッシュ化する。
・JSONファイルの更新日が前日以前であればHTMLの取得をおこない、JSONファイルを保存する。
・JSONファイルの更新日が今日であればキャッシュファイルをみにいく。

<?php
//php上のファイルの情報をキャッシュクリアする
clearstatcache();

//保存するjsonファイル名
$filename = 'tipsnote.json';

// 今日の日付を取得
$todayDate = date("Y/m/d");

//$filename が存在するとき
if (file_exists($filename)) {

  //$filename の更新時刻が過去のとき
  if ($todayDate > date("Y/m/d", filemtime($filename))) {
    scraping($filename);
  }

//$filename が存在しないとき
} else {
  scraping($filename);
}

//スクレイピング処理を関数化
function scraping($filename) {

  // phpQueryの読み込み
  require_once("phpQuery-onefile.php");
  // HTMLの取得
  $doc = phpQuery::newDocumentFile("https://www.tam-tam.co.jp/tipsnote/");

  foreach ($doc[".l-main"]->find(".entry-box") as $entry){
  //更新日
    $date = pq($entry)->find('time')->attr('datetime');
  //タイトル
    $h1 = pq($entry)->find('h1')->text();
  //配列に格納
    $jsonData[] = ['title' => $h1, 'date' => $date];
  }

  //JSONデータを保存
  file_put_contents($filename, json_encode($jsonData,JSON_UNESCAPED_UNICODE));

}

//JSONデータを出力
header(" Content-Type:application/json; charset=utf-8");
echo file_get_contents($filename);

まとめ

PHP初心者の私でも意外と簡単にHTMLの抽出をする事ができました。
PHPをちょっと勉強してみたいっていう人の手始めにちょうどいいのではないでしょうか。

参考サイト

スクレイピング/DOM操作をjQuery風に行う(phpQuery) - Build Insider
【phpQuery】で簡単WEBスクレイピング!をしてみた。

新しいウェブ体験を作ろう TAMのPWA開発
お問い合わせはこちら