PHPでクローラーってどうやるの?よく聞かれます。
特にアフィリエイターの人とか良く聞かれますね、PHP覚えるとっかかりにでもなれば良いと思っているので、スクレイピングの方法を紹介したいと思います。
恐らくこの講座は長くなると思うので3部作ぐらいに分けて解説していきます。
もちろんOOPなんて筆者も未だに苦手なので知らなくてもOKです。
クローラーとは
クローラーとかクロールとかSEO界隈の話やPHPなどのプログラミングを勉強していると良く耳にすると思います。
簡単に言うとクローラーとはBotの事で、自動的に決められた時間の間隔で定期的に巡回しに行くと言うBOTの事をクローラーと言います。
そして、定期的に巡回する事を指してクロールと言います。
あの検索エンジンGoogleやYahooなどもクローラーを使って定期的にWebサイトを監視して検索結果を出しています。
その時に取得したデータをサーチエンジンのサーバーは保存しています。
上記のようにキャッシュと言うリンクの先が実際のGoogleがクロールした時に保存したデータとなります。
クローラーの動作の流れ
クローラーについては大体理解して頂いたかと思いますが、クローラーと一言で行ってもいろいろなクローラーがあります。
画像収集に特化したクローラーやRSSを巡回して記事のタイトルだけを収集するようなクローラーもありますし、アンテナサイトで使われるような記事のタイトルと画像を拾ってくるクローラーも存在しています。
裏ワザ的な使い方では、文章自動生成と組み合わせて他人の記事を自動リライトして構築するような自動サテライトサイト生成クローラーなんてものも作ろうと思えば作れるはずです。
どのクローラーにしても一定の流れを踏んでいますので説明出来ます。
- トリガー実行
- クローラープログラムの動作
- クローラー終了
ざっくりクローラーの流れはこうです。
トリガー
トリガーとは簡単に説明すると起爆剤です。
起動するタイミングを指定する為の【引き金】です、一般的には定期巡回であればCRONで定期実行されていますが、他にもトリガーの方法はあります。
- CRONトリガー
- メール着信トリガー
- ユーザー訪問トリガー
- クリックトリガー
定期実行する場合はCRONで十分ですが、他にも楽天銀行からメールが来た時に自動で処理するような事もトリガー(メール着信)として出来ますし、自分のWebサイトにユーザーが訪れた際に実行させるような事も可能です。
クリックトリガーはユーザーがWebサイトの特定のボタンを押した時にPHPなどのプログラムを実行すると言う事も・・・例えばユーザーのリファラーを見て成果として記録させたり、リファラー先のWebサイトに通知を出したりと言う事も出来ます。
クローラーの作り方講座の心の準備
今回の講座はトリガーが発動されてクローラーが実行される、そのクローラーを作る流れを解説していきます。
- ライブラリのインストール
- スクレイピング
- データ加工
- DBへ追加したり、WP・無料ブログへの投稿など
- CRONで自動化
あれ?こうやって文章にして書いてしまえば、なんかすごくあっさりしてる印象ですが、実際はもう少し濃い内容を書いて行こうと思います。
それでは、必要なライブラリのインストールをするわけですが、ここで必要になるのがComposerです。
Composer持ってねぇよ!って人も居ると思います、何しろ初心者向け講座ですから、そこら辺もきっちり解説していきますよ。
Composerのインストール
Composerはライブラリをインストールするのにコマンドラインから出来る非常に便利なやつです。
厳密に言うとライブラリの依存関係とか調べて必要なパッケージを全部自動で拾ってきてくれる奴です。
開発環境がWindowsならexeファイルを公式サイトからダウンロードしてきて、ダブルクリックしてインストールするだけです。
Macの場合はこのページを参考にしながらインストールして下さい。
私はBrewなんてわからないので・・・・(汗
必要なライブラリとインストール
Composerのインストールが終わった所で必要になるライブラリを紹介したいと思います。
- Guzzle6
- symfony/dom-crawler
はい、ライブラリはこの2つだけです。
スクレイピングの後でWPに投稿したい場合は別途XML_RPC投稿用のライブラリを使った方が便利ですね。
アンテナサイトなどのクローラーの場合は
アンテナサイトのクローラーは上記のライブラリなどは必要無く、RSSを読み込んでタイトルと画像を引っ張ってくると言うのが一般的なアンテナサイトで動くクローラーです。
RSSを読み込んでクロールするURLを取得したい場合はRSSパーサーとかあっても良いですが、私の場合は基本PHPプレーンで、ちゃちゃと取得してます。
RSSをPHPでサクッと取得する流れ
ガッツリ取得してごにょごにょしたいならMagipeeとか使いますが別に<[cdata]>とか取得したい場合はまた別ですけど、その場合もfile_get_contentsで取得した後で<[ ]>を編集してから処理すれば問題無く簡単に取得出来ちゃいます。
$rss = '取得したいURL'; $xml = simplexml_load_file($rss); $parse = json_decode(json_encode($xml),true); $item = $parse['item'];
簡単に言うとこれだけです。
$rssの部分で取得したいRSSのURLを格納しておきます。
後は$itemをvar_dumpなどして中身を確認しながらforeachで欲しい項目を抜き出すだけです。
Guzzleライブラリのインストール
さて、それでは、Composerを使って上記のライブラリを取得したいと思います。
Windowsの場合はXAMPのhtdocsの好きなフォルダを作って、SHIFTを押しながら右クリックで『コマンドウィンドウをここで開く』を選択してCMDを出せば早いです。
composer require guzzlehttp/guzzle:~6.0
とすれば、インストール完了します。
そして、symfony/domclawler も同様に、インストールします。
composer require symfony/dom-crawler
で、完了です。
コマンドラインからのインストールで1個ずつインストールするのが面倒な人は、フォルダ内に、composer.jsonと言うファイル名でファイルを新規制作します。
{ "require": { "guzzlehttp/guzzle": "~6.0", "symfony/dom-crawler": "3.3.4" } }
上記のように書いた後で。
composer install
としてやれば、フォルダ内にvendorと言う名前のフォルダが作られて、そこにライブラリがインストールされているはずです。
今インストールした、Guzzle6はHTTPクライアントです。
しかも、超万能な機能を備えていますから、簡単に100クライアント接続なんて荒業も出来てしまいます。
もちろんPHPプレーン関数のCURLを使っても同じ事が出来ますが、コード量が多くなり過ぎてしまうのと、コード管理が煩雑になりコード修正が面倒だったりデバッグが意味不明な事になり、メンテナンス性が著しく低下していまう為にコード量が少なくて済むGuzzle6のライブラリを利用しています。
その他、ユーザーエージェントを偽装したり、Cookieを保持したり、自動でログインしてくれたりと、いろいろ便利な事が少しのプログラムを書くだけで出来てしまうのです。
symfony/dom-crawler は、スクレイピングに役立つライブラリで、例えば、.content の中の3個のspanのテキストが欲しいとか、attrが欲しいとか、src属性の値を取得したいと結構自由に何でも取ってくる事が出来ます。
ターゲットサイトを巡回する
さて、それではターゲットとなるサイトの情報を取得してみましょう。
まずはindex.phpのファイルを制作します。
その中に、以下のコードを書き込みます。
<?php ini_set('display_errors','1'); require 'vendor/autoload.php'; use GuzzleHttp\Promise; use GuzzleHttp\Pool; use GuzzleHttp\Clinet; $client = new \GuzzleHttp\Client( [ 'cookies' => true, 'base_uri' => 'https://www.yahoo.co.jp', 'headers' => [ 'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; rv:38.0) Gecko/20100101 Firefox/38.0', ] ] );
Guzzleを使う上で上記はお約束だと思って下さい。
Guzzleの機能を利用するよーと言う宣言文みたいなものです。
requireの部分はライブラリを一括で読み込んでいます。
ヤフー日本のデータを取得してみるテスト
これから、Yahooのデータを取得してみるわけですが、気を付けたいのはスパムにならないように気を使う事と、一気に大量のアクセスを送ったりして、相手のサーバーに負荷を掛け過ぎない様に考慮して使うようにして下さい。
$response = $client->request('GET', 'https://www.yahoo.co.jp'); $crawler = new Symfony\Component\DomCrawler\Crawler((string)$response->getBody()); var_dump($crawler->html());
先程のお約束のプログラムに続けて上記3行を追加して実行してみて下さい。
Objectの状態ですが、Yahooのトップページのデータを拾ってこれたと思います。
ちなみに最後の行で
echo $crawler->html();
とするとYahooが表示されます。
Yahooのリアルタイム検索ワードをスクレイピングする
それでは肩慣らしに、Yahooのリアルタイム検索ワードをスクレイピングして拾ってみましょう。
上記画像の赤枠の中のキーワードを拾うにはどうするか?
GoogleChromeでYahooのページを開いてF12を押します
そうするとこのようなChromeデベロッパーツールのウィンドウが開きます。
ウィンドウ別で開かない場合は、Chromeのウィンドウの下部を見て下さい。
何か小さい窓開いてませんか?それがChromeデベロッパーツールです。
YahooのHTMLを解析する
デベロッパーツールのウィンドウの一番左上の矢印ボタンを選択してから、Yahooウィンドウのリアルタイム検索ワードを選択します。
該当ソースコードの上にカーソルを持って行き右クリック!えいっ!
出てきたメニューからcopy→Copy XPath を選択するとクリップボードにキーワードまでのXPathが格納されます。
そしたら、PHPコードに戻って、コピーしたXPathを貼り付けてコードを完成させます。
echo $crawler->filterXPath('//*[@id="RealtimeRanking"]/div[2]/div[1]/ol/li[1]/div/p/a')->text();
はい、最後の一行を編集するだけですね。
Var_dump(….から始まってる部分を上記に書き換えるだけです。
実行してみて下さい。
現執筆辞典ではスクショの通り『尾根』が表示されており、その横にカメラマークのアイコンがついていました。
従って表示は『根尾写真』と表示されていれば正解です。
どうでしょう?簡単だったでしょう?いわゆるこれがスクレイピング(クローラー)と言うものです。
実際のクローラーは定期的にこのスクリプトを実行させ、リアルタイムキーワードのランキングを1位~5位まで取得する作業を繰り返す事で、常に最近のキーワードを取得し続ける事が出来ます。
その際には少々表示関係を修正しなければいけないのと、5つのキーワードを取得するように修正する必要がありそうです。
次のチュートリアルはこちら

コメント
[…] 前回の記事はいかがでしたでしょうか? […]