Personlink

WEB技術

【phpQuery】で簡単WEBスクレイピング!をしてみた。

2015年5月16日 by 1

top_web_scraping_hikaru_20150516

GWも終わってしまい、なんと6月は祝日がありません!7月の海の日まで祝日が無い絶望感に包まれた時にエンジニアがやりたくなる事と言えば・・・

そう!WEBスクレイピングですね!

今回はPHPで手軽にスクレイピングする方法を書いていきます。

仕事の8割は検索と徘徊に費やす系エンジニア田中です。

「スクレイピング」とか「クローリング」って何?

そもそもスクレイピングとは何なのか?Google翻訳さんによると「こすること」と出ます。

ちなみに「クローリング」は「巡回すること」です。

イメージとしては、WEB上にあるHTMLコンテンツを「クローリング(巡回)」して、欲しい情報を「スクレイピング(擦り取る)」という感じです。

「抽出」にあたる「Extract」とかを使わない辺りが、エンジニアの執念の垣間見える作業だということを物語っていますねw

用意するもの

- PHPが使える

- ネットに繋がる

- 優秀な頭脳

これだけあればスクレイピングの準備はばっちりです。

参考にするサイト

今回はPHPでjQueryっぽくHTMLを操作出来る「phpQuery」を使います。

** https://code.google.com/p/phpquery/

ソースを取ってくる

phpQueryを使うのはとっても簡単です。

ソースを取ってきてrequire_once(“phpQuery-onefile.php”);で完了です。

** https://code.google.com/p/phpquery/downloads/list

ここの中の最新の「phpQuery-...-onefile.zip」をクリックします。

ダウンロードのリンクが表示されるので右クリックでリンク先をコピーして

wget https://phpquery.googlecode.com/files/phpQuery-*.*.*.*-onefile.zip

でzipを取ってきます。

取ってきたzipはunzipでサクッと解凍!

unzip phpQuery-...-onefile.zip

そうすると「phpQuery-onefile.php」というファイルが出来ているのでこれでOKです。

さっそく使ってみる

今回は弊社ブログ記事のタイトルと中の小見出しを抽出してみます。

まずは各記事のリンク先を抽出します。

** https://person-link.co.jp/

これを取ってくるのは便利な「file_get_contents」という関数です。

ローカルにあるファイルはもちろん、URLを引数に渡してあげるとHTMLを取得する事が出来ちゃういます。

第二引数にプロキシを設定する事も出来ますが今回は割愛です。詳しくは公式リファレンスにてご確認下さい。

** http://php.net/manual/ja/function.file-get-contents.php

とりあえずこんな感じです。

あとは$phpQueryObjからjQueryっぽくDOMを取得してくるだけです。

find(‘a’)->attr(‘href’).PHP_EOL; } ?>

今回地味にはまったのがここです。

取得してきた$titleArrの要素はDOMElementとして認識されていて、phpQueryの支配下から外れてしまうんですね。

** http://php.net/manual/ja/class.domelement.php

なのでphpQueryのメソッドを使える様に「pq()」メソッドで再定義してあげた上で中の要素を取得する、という小技が必要でした。(ハマり目安:時間5分)

子ページを取得する

ここまで理解が出来ればあとは簡単! 同じ要領で子ページのタイトルを取得してきましょう!

$val) { $komidashi = pq($val)->text(); echo ‘小見出し’. $i .’:’ . $komidashi . PHP_EOL; } } ?>

整える

あとは作った関数の呼び出し元をちゃんと整理して、コンソールにぼこぼこ出力されるようにしましょう!

find(‘a’)->text(); $url = pq($val)->find(‘a’)->attr(‘href’); echo ‘タイトル:’ . $title . PHP_EOL; echo ‘ページURL:’. $url . PHP_EOL; getChiledPage($url);

echo PHP_EOL.PHP_EOL; }

/**

  • もろもろ競合しちゃうと嫌なので関数化

  • 小見出しを取得して出力

  • @param string $url 子ページのURL */ function getChiledPage($url) { // ページを取得してオブジェクト化! $phpQueryObj = phpQuery::newDocument(file_get_contents($url));

    // ループでぶん回す foreach($phpQueryObj[‘h2’] as $i => $val) { $komidashi = pq($val)->text(); echo ‘小見出し[’. $i .’]:’ . $komidashi . PHP_EOL; } } ?>

関数の呼び出し元のforeachの中に書いてある「sleep(5)」はとても大切で、弊社のHPのように弱小インフラで運用しているサービスは、連続で多数のリクエストを要求されると簡単にぶっ飛びますw

本当は外に出した関数の中でechoするのは好ましく無いとか変数名が雑とか色々ありますが、個人の趣味程度であればこれで勘弁して欲しいところですw

悪用は厳禁なんだよ!

情報を素早く集めるために、WEBを使いプログラムを使い、とても便利な世の中になりましたが、もちろんこれは人類の文化的な発展のために作られたものですので、XXXがXXXをXXXするために使ったりしたらいけないんです!

連続リクエストによって偽計業務妨害容疑で逮捕されたという事件がありますので、本当にリクエストの回数と間隔にはお気を付け下さいませ。

参考:岡崎市立中央図書館事件 - Wikipedia

秒間1リクエストまでになるように考慮してもサーバーがぶっ飛べば逮捕される恐れがあるということです。 くれぐれも迷惑をかけないように気を付けましょう!

おわり

ルールとモラルを守って次の祝日まで楽しいスクレイピングライフをお送りくださいませ!