PHPでWebスクレイピングをする【サンプル付き】

Webサイトの調査やマーケティング関連の業務の時に、スクレイピングを使うと業務を自動化できてとても便利ですよね。

phpでスクレイピングをする場合は、phpQueryを使うと簡単です。
今回は、phpQueryを使ったスクレイピング方法についてまとめました。

基本的な使い方から、実用的な方法までまとめています。
参考になればと思います。

基本編:phpQueryの使い方

phpQueryは、jqueryのようにDOM操作ができるライブラリです。

ライブラリ追加

composerを使ってライブラリをインストールします。
プロジェクトにcomposerが無ければ、以下のコマンドで初期化します。

$ composer init

ライブラリを追加します。

$ composer require electrolinux/phpquery

autoloadfile作成します。

$ composer dumpautoload

phpQueryを読み込み

autoloadファイルを読み込んで、phpQueryが利用できるようにします。

require_once "vendor/autoload.php";

HTMLの読み込み

最初にHTMLを読み込んで、クラスを初期化します。

$url = 'https://blog.hiroyuki90.com/';
$html = file_get_contents($url);
$dom = \phpQuery::newDocument($html);

もしくは、urlを直接指定します。

$url = 'https://blog.hiroyuki90.com/';
$dom = \phpQuery::newDocumentFile($url);

セレクタを指定して取得

セレクタの指定の仕方です。
ほぼjQueryのように使うことができます。

要素を指定

要素を指定して取得します。

$dom['h1'];

IDを指定

IDを指定して取得します。

$dom['#sitename'];

classを指定

classを指定して取得します。

$dom['.article-list'];

複数のセレクタを指定

複数のセレクタを指定して取得できます。

$dom['h1, h2'];

子要素を指定

子要素を指定することもできます。

$dom['h1 > a'];

その他

他にも、指定できるセレクタは公式ドキュメントを参考にしてみてください。
https://code.google.com/archive/p/phpquery/wikis/Selectors.wiki

値の取得や変更

属性

a要素のhrefを取得します。

$dom['h1 > a']->attr('href');

a要素のhrefを変更します。

$dom['h1 > a']->attr('href', 'https://www.yahoo.co.jp/');

クラス

クラスを追加します。

$dom['h1']->addClass('heading');

クラスを削除します。

$dom['h1']->removeClass('header-sitename');

テキスト

テキストを取得します。

$dom['h1 > a']->text();

テキストを変更する場合は、値を渡します。

$dom['h1 > a']->text('サイト名');

その他

他には、htmlでHTMLを取得・変更したり、valで属性の取得・変更することができます。
https://code.google.com/archive/p/phpquery/wikis/Selectors.wiki

DOMの変更

追加

要素を子要素の最後に追加します。

$elem = \pq('<span>');
$elem->text('テキスト');

$dom['h1']->append($elem);

pq関数は、jQueryの$()と同様の関数で、
span要素を生成してテキストをセットし、h1に追加しています。

子要素の最初に追加する場合は、prependを使います。

$elem = \pq('<span>');
$elem->text('テキスト');

$dom['h1']->prepend($elem);

変更

要素を置換します。

$elem = \pq('<span>');
$elem->text('テキスト');

$dom['h1']->replaceWith($elem);

追加の時と同様に、pq関数を使い、要素を生成して、h1を置換しています。

削除

emptyを使うと、子要素が全て削除されます。

$dom['h1']->empty();

removeを使うと、要素ごと削除されます。

$dom['h1']->remove();

その他

jQueryのようにprependafterbefore などの関数が利用できます。
https://code.google.com/archive/p/phpquery/wikis/Selectors.wiki

実用編:Webサイトをスクレイピングしてみる

お題として、本ブログのトップページにアクセスして、
記事一覧のタイトル・URLのリスト取得します。
ページャーがついていますので、最後のページまで取得します。

まずはWebサイトの仕様を把握する

Webサイトをスクレイピングして、情報を正しく取得するには、仕様を把握する必要があります。

本ブログの場合は、

  • ページが変わった場合は、/page/○○のようなURLになる。
  • 記事のリストは、.article-list > .article-itemに並んでいる。

ということが分かれば、正しく記事のリストを取得することができます。

実装してみる

先にソースコードを挙げると、こちらのようになります。

<?php

require_once "vendor/autoload.php";

$baseUrl = 'https://blog.hiroyuki90.com';
$startPage = 1;
$maxPage = 3;

$posts = [];

// - ① 
foreach (range($startPage, $maxPage) as $page) {
    $url = "{$baseUrl}/page/{$page}";

    $dom = \phpQuery::newDocumentFile($url);

    // - ②
    foreach ($dom['.article-list > .article-item'] as $row) {
        // - ③
        $title = pq($row)->find('h2')->text();
        $url = pq($row)->find('a')->attr('href');

        $posts[] = [
            'title' => $title,
            'url' => $url,
        ];
    }
}

var_dump($posts);

の部分で、ページを1〜3まで順番に取得して、HTMLを取得します。

の部分で、記事のリストを取得して順番に処理しています。

の処理にて、記事のタイトル・URLを取得して配列に結果を保存しています。

以上で完了です。

簡単なサンプルになりますが、スクレイピングの基礎としてこんな感じです。

さいごに

今回は、phpQueryの基本的な使い方を、簡単なサンプルを交えてまとめてみました。

認証が必要なWebサイトのクロールなど、後々追加していこうと思います。