PHPでWebスクレイピング

2021/12/19

「WEBサイトから欲しい情報を集めたい」そんなことはありませんか?

外部のWEBサイトからデータを抽出して表示させる方法は大きく2通りあります。

1.APIを使用する
2.Webスクレイピング

このうち、今回は 「Webスクレイピング」 を使ってデータを抽出して表示させるプログラムを作成してみようと思います。

Webスクレイピングとはホームページからデータを抜き取る方法のことです。

PHPでは「phpQuery」という便利なスクレイピングのライブラリがあるので、それを利用します。

 

完成形

connpass(IT勉強会支援プラットフォーム)から「Laravel」に関するイベント&勉強会を抽出して、表示させてみます。

キーワード:laravel|connpass

 
connpass では API が用意されているのですが、今回は手軽るにWebスクレイピングで抽出してみます。

デモページは以下になります。

 
ソースコードはGit Hubに上げています。

Webスクレイピング|Git Hub

 

手順

1.phpQueryをダウンロード

phpQueryのダウンロードページから最新の「phpQuery-...onefile.zip」をダウンロードします。

phpquery |Google Code

 
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です。

 
以上です。

PHP おススメ教材(by Udemy)

 

本庄マサノリ

仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら

>> Twitter をフォローする

 

-周辺知識