アクアリウムハジメマシタ!!

PHPでスクレイピング

PHPでスクレイピングして画像をダウンロードする方法

今回ある案件でいったんどうしてもスクレイピングが必要になったのですが、レンタルサーバーだったこともありPythonじゃなくてPHPでwebスクレイピングをやることになりました。PHPでのスクレイピングは以前やったことはあるのですが、数年ぶりなので「PHPQueryってまだあるのかな?」なんて思いながらやってみたので、備忘録代わりに記事にしておきます。ただ、PHPQueryが2009年以来更新されてないのが不安です・・・。まぁスクレイピング自体は簡単ですが、その後のデータの取り出しだったり、保存だったり、活用だったりがやはり難しいですね。

スクレイピングとは!?

スクレイピング(webスクレイピング)とはウェブサイトからある情報を抽出する、取得するための技術のことです。
ただし!このスクレイピング(webスクレイピング)はターゲットサイトにとって迷惑な行動でもあるので、悪用したりは厳禁です!
ちなみにLibrahack事件といって岡崎市の図書館のサイトに高頻度のリクエストを故意に送りつけたとして偽計業務妨害容疑で逮捕されるという事件も発生しています。

スクレイピングにおける問題点

  • 取得した情報を利用する場合の著作権法上の問題
  • ターゲットサイトの利用規約との抵触
  • サイトやサーバへの過度なアクセス

PHPQueryとは!?

PHPQueryはまるでjQueryのようにDOM操作ができるPHP用のライブラリです。
スクレイピングにおいてはDOM操作を複数回繰り返すことが前提になるので、こういったDOMを操作しやすいライブラリを使います。

1

PHPでスクレイピング

ダウンロードするデータは最新版のphpQuery-○.○.○.○○○-onefile.zipとなっているリンクを選択してクリックします。「-onefile.zip」となっている方なので注意してください。

2

PHPでスクレイピング

PHPでスクレイピング

ダウンロードが完了したら上の画像のようにファイルを配置します。この時index.phpにはまだ何もかかれていません。この先index.phpを編集していくことになります。もちろんファイルの配置については開発に合わせてお好みで配置してください。

これだけでPHPQueryを使う準備が整いました。ローカル開発するのかサーバ上で開発するのかはさておき、準備はこれだけなのでPHPQueryは手軽に始められていいですね。さて、次は実際にwebサイトをスクレイピングしていこうと思います。

PHPQueryの使い方(実際にスクレイピングしてみる)

ファイルの配置が完了したところで早速PHPQueryを使っていきます。
PHPQueryを使うにはまずはindex.phpから「require_once」します。もちろん「phpQuery-onefile.php」へのパスはそれぞれの環境に合わせたパスに変更してください。

require_once("phpQuery-onefile.php”);

次はこちらのcomplesso.jpのトップページをスクレイピングしてみます。ターゲットとなるURLを変数にセットします。

$targetUrl = "https://complesso.jp";

次はfile_get_contents関数でターゲットサイトのHTMLデータを取得します。今回はいったん$htmlに代入します。

$html = file_get_contents($targetUrl);

取得した文字列から今度はh2タグを探して出力します。complesso.jpのトップページの場合h2タグは記事タイルのタイトルになっています。

complesso.jpのトップページ

PHPでスクレイピング


いよいよPHPQueryでh2タグの内容を出力します。PHPQueryで要素の中のテキストを取得して表示するにはtext()を使います。

echo phpQuery::newDocument($html)->find("h2")->text();

これでindex.phpをブラウザで開くと以下の画像のように無事要素の内容が出力されていれば成功です。

complesso.jpのトップページ

PHPでスクレイピング

通常配列に格納した方がデータは使いやすいので、今回は$h2Listという配列にh2要素の値を格納してみます。
配列に格納する場合はいったんHTMLのデータをPHPQueryのオブジェクト化します。

$htmlData = phpQuery::newDocument($html);

さきにh2のテキストを格納する配列を定義します。

$h2List = array();

さらに$htmlDataからphpQueryのfind()を使ってh2を探し、$findH2Listに格納します。

$findH2List = $htmlData->find("h2");

このあとはおなじみのforeachでデータを順に$h2Listに格納していきます。

$i=0;
foreach($findH2List as $h2) {
    $h2List[$i] = $h2;
    $i++;
}

これで配列の内容を見てみると・・・

complesso.jpのトップページ

PHPでスクレイピング

無事格納されてますね。

PHPQueryいろいろ

PHPQueryの使い方はだいたい理解できたので少しセレクタの指定方法をいろいろと見ていきたいと思います。

HTMLの要素指定

HTML要素というのはh1やh2、a、pなどのことです。

phpQuery::newDocument($html)->find("h1")->text();

idの属性指定

idは「id=”test-id”」となっているtest-idのことですね。idを指定したい場合は「.」をつけるので、test-idを指定したい場合は次のように指定します。

phpQuery::newDocument($html)->find(".test-id")->text();

classの指定

classは「class=”test-class”」のようになっているtest-classのことです。classを指定したい場合は「#」をつけるので、test-classを指定したい場合は次のように指定します。

phpQuery::newDocument($html)->find("#test-class")->text();

複数のセレクタを指定

PHPQueryでは複数のセレクタを指定することもできるようです。複数のセレクタを指定したい場合は「,」で区切って次のように指定します。

phpQuery::newDocument($html)->find("h1,h2")->text();

子要素を指定

子要素の指定も簡単にできるようです。子要素を指定する場合は次のように順に「>」でつなげます。

phpQuery::newDocument($html)->find("test-class > a")->text();