Webスクレイピングが捗るGoutteを使ってみる
- カテゴリ :
- バックエンド(プログラミング)
- タグ :
- Tech
- PHP
- Goutte
- Webスクレイピング
シャワー後の水切りでヘドバンしてたら頸椎を痛めてしまいました。あれは絶対やめた方がいいです。と周囲に広めているたきゃはしです。急に本題ですが今回はPHPで簡単にできるWebスクレイピングをご紹介します。
◯ Webスクレイピングとは
Webサイトからデータを抽出するソフトウェア技術のことです。
RSSやWebAPIが公開されていないサイトからでもデータ抽出が出来るようなイメージです。
早速クローラーの Goutte(グットゥ) を使って紹介していきたいと思います。
Goutte は Symfony や Twig、Pimple等の開発者として知られるFabienが手がける人気ライブラリです。
◯ インストール
- php
composer.phar require fabpot/goutte:~2.0
- ...
"require": { "php": ">=5.4.0", "symfony/browser-kit": "~2.1", "symfony/css-selector": "~2.1", "symfony/dom-crawler": "~2.1", "guzzlehttp/guzzle": "4.*" }, ...
話が逸れますが、使用するライブラリの依存コンポーネントを確認しておくことは大切かなと思います。
◯ 使ってみる
- //
first.php - require_once
'./vendor/autoload.php'; - $client
= new Goutte\Client(); - $crawler
= $client->request('GET', 'http://blog.asial.co.jp/'); - //
抽出 - $targetSelector
= 'h2.lh1_2em'; // アシアルブログの見出しのセレクター - $crawler->filter($target)->each(function
($node) { echo $node->text() . "\n"; - });
- ~/Sites/prac/goutte
php first.php 外部コンテンツをiframeサイズで拡大縮小させたり、固定幅コンテンツをウィンドウサイズでピッタリ表示させる方法 「Monaca for Hybridcast」CEATEC JAPAN 2014(2014/10/7-11開催)にて展示 お絵描きアプリと画像の保存処理の実装 PC/スマホでは無いWEBアプリ開発の話 -ハイブリッドキャスト編- IllustratorでSVGファイルを保存してみました iPhone6 PlusのPSDモックアップとAppleのフォント Canvas Fingerprintingというトラッキング技術 HTML5プロフェッショナル認定試験のセミナー資料を公開します 弊社田中のコラム「エンタープライズHTML5とバックエンド─エンタープライズ×モバイルアプリ開発の最新動向」が公開されました HTML5+CSS3+JSでネイティブGUIアプリが作れる、node-webkitを触ってみる
コードにしれっと出てきた $client と $crawler について確認してみたいと思います。
・$client Goutte\Client
- Array
- (
[0] => setClient [1] => getClient [2] => setHeader [3] => removeHeader [4] => setAuth [5] => resetAuth [6] => __construct [7] => followRedirects [8] => setMaxRedirects [9] => insulate [10] => setServerParameters [11] => setServerParameter [12] => getServerParameter [13] => getHistory [14] => getCookieJar [15] => getCrawler [16] => getInternalResponse [17] => getResponse [18] => getInternalRequest [19] => getRequest [20] => click [21] => submit [22] => request [23] => back [24] => forward [25] => reload [26] => followRedirect [27] => restart - )
このオブジェクトの役割はブラウザもしくはページそのものみたいな感覚でいいかなと思います。
click, submit, request, back, forward, reload, restart あたり覚えておけば良さそうです。
・$crawler Symfony\Component\DomCrawler\Crawler
- Array
- (
[0] => __construct [1] => clear [2] => add [3] => addContent [4] => addHtmlContent [5] => addXmlContent [6] => addDocument [7] => addNodeList [8] => addNodes [9] => addNode [10] => eq [11] => each [12] => reduce [13] => first [14] => last [15] => siblings [16] => nextAll [17] => previousAll [18] => parents [19] => children [20] => attr [21] => text [22] => html [23] => extract [24] => filterXPath [25] => filter [26] => selectLink [27] => selectButton [28] => link [29] => links [30] => form [31] => setDefaultNamespacePrefix [32] => registerNamespace [33] => xpathLiteral [34] => getNode [35] => attach [36] => detach [37] => contains [38] => addAll [39] => removeAll [40] => removeAllExcept [41] => getInfo [42] => setInfo [43] => getHash [44] => count [45] => rewind [46] => valid [47] => key [48] => current [49] => next [50] => unserialize [51] => serialize [52] => offsetExists [53] => offsetSet [54] => offsetUnset [55] => offsetGet - )
クローラーオブジェクトの役割はデータ抽出の作業者でよさそうです。
eq, attr, text, html, extract, selectLink, selectButton, link, links, form あたり覚えておけば良さそうです。
配列操作だと each, first, last, filter, contains, count あたりはよく使いそうですね。
さて、クライアントやクローラの内容をちょこっと予習できたところで、他の操作もしてみたいと思います。
・テキストリンクをクリックする
- ...
- //
リンクのテキストをクリックする - $targetLinkText
= 'バックエンド(プログラミング)'; - $link
= $crawler->selectLink($targetLinkText)->link(); - $crawler
= $client->click($link);
・ボタンをクリックする
- ...
- //
ボタンのテキストをクリックする - $targetButtonText
= '検索'; - $button
= $crawler->selectButton($targetButtonText)->form(); - $crawler
= $client->click($button);
inputタグでも出来ることが分かって良かったです。(type=imageのaltテキストを対象にしました。)
・フォームを送信する
- ...
- //
指定テキストで検索する - $targetButtonText
= '検索'; - $form
= $crawler->selectButton($targetButtonText)->form(); - $searchParameters
= ['words' => 'Monaca']; - $crawler
= $client->submit($form, $searchParameters);
また$clientはリクエスト&レスポンスを持っていました。以下のメソッドが定義されています。
・Symfony\Component\BrowserKit\Request
- Array
- (
[0] => __construct [1] => getUri [2] => getMethod [3] => getParameters [4] => getFiles [5] => getCookies [6] => getServer [7] => getContent - )
・Symfony\Component\BrowserKit\Response
- Array
- (
[0] => __construct [1] => __toString [2] => getContent [3] => getStatus [4] => getHeaders [5] => getHeader - )
また記事作成中に知った機能ですが、Chrome Developer Tools > Copy CSS Path(画像参照) がセレクター取得に便利でした。
◯ まとめ
Goutteでスクレイピングしてみて良かったなぁという点は...
- めちゃくちゃ簡単にスクレイピングできること。
- 手作業に比べて圧倒的に高速かつ正確なこと。
- 人間が詳細な作業内容を覚える必要がないこと。
- 作業という単位でコンポーネント化しやすいので開発がどんどん楽になりそうなこと。
- ちょっとずれるけど、PHPUnitと連携すれば画面テストにも利用できること。
逆に課題かなぁと感じた点は...
- プログラムがWebサイトの稼働状況やDOM構造に依存しているため安定稼働が難しいこと。
- 自動化する場合は対象のDOM構造が変更されていないか監視する機能が必要なこと。
- 変更があれば効率よく開発者へ通知するためのロギング機能や通知処理が必要なこと。
- 変更があれば抽出ミスが発生するため、エラー処理やリカバリが必要なこと。
要約すると、すごい便利なんだけど作りこまないと運用大変そうだなぁという感じでした。
今更言うことではないですが、規約に反する行為および抽出データの取り扱いにはくれぐれもご注意を。
それでは皆様、健全で生産的なスクレイピングを楽しみましょう!