2021/12/19
「WEBサイトから欲しい情報を集めたい」そんなことはありませんか?
外部のWEBサイトからデータを抽出して表示させる方法は大きく2通りあります。
1.APIを使用する
2.Webスクレイピング
このうち、今回は 「Webスクレイピング」 を使ってデータを抽出して表示させるプログラムを作成してみようと思います。
PHPでは「phpQuery」という便利なスクレイピングのライブラリがあるので、それを利用します。
完成形
connpass(IT勉強会支援プラットフォーム)から「Laravel」に関するイベント&勉強会を抽出して、表示させてみます。
connpass では API が用意されているのですが、今回は手軽るにWebスクレイピングで抽出してみます。
デモページは以下になります。
ソースコードはGit Hubに上げています。
手順
1.phpQueryをダウンロード
phpQueryのダウンロードページから最新の「phpQuery-...onefile.zip」をダウンロードします。
Zipファイルを解凍したら中にある「phpQuery-onefile.php」を好きなところに配置します。
root/
├ index.php
└ phpQuery-onefile.php
2.PHPの記述
# phpQueryを読み込む
require_once("./phpQuery-onefile.php");
# 日付パラメーター
$from = date("Y/m/d"); //今日
$to = date("Y/m/d", strtotime("6 month")); //6ヶ月加算
# 取得したいwebサイトを読み込む
$html = file_get_contents("https://connpass.com/search/?q=laravel&start_from=".$from."&start_to=".$to);
# DOM取得
$doc = phpQuery::newDocument($html);
DOMで取得したデータは以下のようにセレクタを指定して表示させます。
:
# 要素取得
echo $doc[".year:eq(0)"]->text()."年 ". $doc[".date:eq(0)"]->text();
echo $doc[".event_title:eq(0)"];
:
$doc[" "]の " "
の中身はjQueryのセレクタが使えるので、基本、jQueryと同じように利用すればOKです。
セレクタとは
セレクタはjQueryを記述する際の$()の中のことを指します。
操作したい要素を指定するために使用します。
$("#contents").css(...
必要な要素に id が振られていれば、操作に苦労はしませんが、一意なidが振られていない場合は、要素の指定にオプションが必要になります。
「phpQuery」セレクタのオプション
:eq() | 指定した番号の要素を取得する |
:even | 偶数の要素を取得する(※0番目から始まります) |
:odd | 奇数の要素を取得する(※0番目から始まります) |
:gt() | 指定した番号以降の要素を取得する |
:lt() | 指定した番号までの要素を取得する |
3.HTMLの記述
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Webスクレイピング デモ</title>
<!--Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<!--Font Awesome5-->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<!--自作CSS -->
<style type="text/css">
<!--
/*ここに調整CSS記述*/
-->
</style>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-light navbar-dark bg-dark">
<a class="navbar-brand" href="#!">Webスクレイピング デモ</a>
</nav>
<!-- Page Content -->
<div class="container mt-5 text-center p-lg-5 bg-light">
<h2 class="mb-5">Laravelの勉強会(by connpass)</h2>
<!--Bootstrapコンポーネントを記述していく-->
<dl class="row" style="text-align: left;">
<?php if($doc[".year:eq(0)"]->text()){ ?>
<dt class="col-sm-3"><?php echo $doc[".year:eq(0)"]->text()."年 ". $doc[".date:eq(0)"]->text(); ?></dt>
<dd class="col-sm-9"><?php echo $doc[".url:eq(0)"]; ?> (参加者数:<?php echo $doc[".amount:eq(0)"]; ?>人)</dd>
<?php }else{ ?>
<dd class="col-sm-12" style="text-align: center;">現在、Laravelの勉強会はありません。</dd>
<?php } ?>
<?php if($doc[".year:eq(1)"]->text()){ ?>
<dt class="col-sm-3"><?php echo $doc[".year:eq(1)"]->text()."年 ". $doc[".date:eq(1)"]->text(); ?></dt>
<dd class="col-sm-9"><?php echo $doc[".url:eq(1)"]; ?> (参加者数:<?php echo $doc[".amount:eq(1)"]; ?>人)</dd>
<?php } ?>
<?php if($doc[".year:eq(2)"]->text()){ ?>
<dt class="col-sm-3"><?php echo $doc[".year:eq(2)"]->text()."年 ". $doc[".date:eq(2)"]->text(); ?></dt>
<dd class="col-sm-9"><?php echo $doc[".url:eq(2)"]; ?> (参加者数:<?php echo $doc[".amount:eq(2)"]; ?>人)</dd>
<?php } ?>
<?php if($doc[".year:eq(3)"]->text()){ ?>
<dt class="col-sm-3"><?php echo $doc[".year:eq(3)"]->text()."年 ". $doc[".date:eq(3)"]->text(); ?></dt>
<dd class="col-sm-9"><?php echo $doc[".url:eq(3)"]; ?> (参加者数:<?php echo $doc[".amount:eq(3)"]; ?>人)</dd>
<?php } ?>
<?php if($doc[".year:eq(4)"]->text()){ ?>
<dt class="col-sm-3"><?php echo $doc[".year:eq(4)"]->text()."年 ". $doc[".date:eq(4)"]->text(); ?></dt>
<dd class="col-sm-9"><?php echo $doc[".url:eq(4)"]; ?> (参加者数:<?php echo $doc[".amount:eq(4)"]; ?>人)</dd>
<?php } ?>
<?php if($doc[".year:eq(5)"]->text()){ ?>
<dt class="col-sm-3"><?php echo $doc[".year:eq(5)"]->text()."年 ". $doc[".date:eq(5)"]->text(); ?></dt>
<dd class="col-sm-9"><?php echo $doc[".url:eq(5)"]; ?> (参加者数:<?php echo $doc[".amount:eq(5)"]; ?>人)</dd>
<?php } ?>
<?php if($doc[".year:eq(6)"]->text()){ ?>
<dt class="col-sm-3"><?php echo $doc[".year:eq(6)"]->text()."年 ". $doc[".date:eq(6)"]->text(); ?></dt>
<dd class="col-sm-9"><?php echo $doc[".url:eq(6)"]; ?> (参加者数:<?php echo $doc[".amount:eq(6)"]; ?>人)</dd>
<?php } ?>
</dl>
</div><!-- /container -->
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" ></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" ></script>
<script>
// aタグ全てにターゲット _blank を設定
$('a').attr('target' , '_blank');
</script>
</body>
</html>
4.動作確認
ローカル環境にてURLにアクセスして、下記のようにデータを取得できたらOKです。
以上です。
仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら。