[PHP]HTMLから全ての画像URLを正規表現で取得する方法
ブログ記事から画像を抜き出したい
わたしは今、とあるアプリを開発中です
いわゆるまとめのまとめ系アプリなのですが、、、
アプリを開発する中で、取得したRSSの記事情報から画像を抜き出したくなりました。
記事のタイトルと一緒に画像も見せたいからです。
そんな時はやっぱり正規表現だね!
PHPでどう書くか
定期的に各ブログさんの記事を収集してDBに放り込む処理はサーバで行っています。
そして、サーバサイドはお手軽簡単なPHPにて構築
PHPで正規表現使うのは下記の関数です
int preg_match ( string $pattern
, string $subject
[, array &$matches
[, int $flags
= 0 [, int $offset
= 0 ]]] )
http://php.net/manual/ja/function.preg-match.php
int preg_match_all ( string $pattern
, string $subject
[, array &$matches
[, int $flags
= PREG_PATTERN_ORDER
[, int$offset
= 0 ]]] )
http://php.net/manual/ja/function.preg-match-all.php
preg_match
preg_matchでは、$subjectで指定した文字列に対して$patternで正規表現検索を行い、返ってきた値を1つ$matchesに保存します。
この時、$matchesは1次元配列となります($matches[])
$matches[0]は検索にひっかかった全ての文字列
$matches[1]は1 番目のキャプチャ用サブパターンにマッチした 文字列
preg_match_all
preg_matchとはことなり、検索に引っかかったものを全て取得します
使い方はpreg_matchと同様、$subjectで指定した文字列に対して$patternで正規表現検索を行います。
また、$matchesは2次元配列となります($matches[][])
配列の中身は$flagsで指定した値によって異なります。
$flags = PREG_PATTERN_ORDER
$matches[0] ・・・ パターン全体にマッチした文字列の配列
$matches[1] ・・・ 第 1 のキャプチャ用サブパターンにマッチした文字列の配列
$flags = PREG_SET_ORDER
$matches[0] ・・・ 1 回目のマッチングでキャプチャした値の配列
$matches[1] ・・・ 2回目のマッチングでキャプチャした値の配列
というかんじですが、基本的にはPREG_PATTERN_ORDERの指定で良いんじゃないかな
($flagsはoptionalなので、指定しない場合はPREG_PATTERN_ORDERとなる)
早く画像の取り方教えろ!
説明はもうおいておいて、、、
(わからんかったら上記リンクのマニュアルを見てください)
私が実際に書いたコードは下記のような感じです。
$rssImage = ''; $preg_string = '/<img.*?src\s*?=\s*?[\"|\'](.*?(jpg|jpeg|gif|png))[\"|\'].*?>/i'; if(preg_match_all($preg_string, $rssDescription, $match, PREG_PATTERN_ORDER) > 0){ // gifは除外(jpenのみ採用) foreach ($match[1] as $image) { if(preg_match('/.*?(jpg|jpeg)/i', $image, $out)){ $rssImage = $image; break; } } echo 'check: ' . $rssImage . PHP_EOL; }
はじめのpreg_match_allで、RSSのdescriptionからすべての画像を取得しています。
全ての画像と言っても、jpg,jpeg,gif,pngだけです。
画像は<img>タグで判断できますね。
<img>タグのsrc部分を抜き出している形です。
/<img.*?src\s*?=\s*?[\”|\’](.*?(jpg|jpeg|gif|png))[\”|\’].*?>/i
この後が問題
画像を取得したはいいけど、gifとかpngとかっていうのはブログ内の絵文字だったりするんですね。
そんなものは必要ない!!
だからpreg_match_allで取れた配列に対して、jpg,jpegのみ採用しているんです。
いやしかし、個人的にはあまり気に入っていないのです。
もっとスマートで良い書き方があると思うのだが、、、
ひとまず機能は満たしてはいるのでおいておくとして
また見直す必要はありそうだ
正規表現をマスターするということ
プログラミングを行う上で、正規表現をマスターすることはマストだと思います。
(私自身まだマスターしていませんが、、、、、、、)
今回のように、スクレイピングを行ったり、はたまたコーディング中のソースコードに対して正規表現での検索をかけて一括置換!!
なんて便利なこともできてしまうわけです。
とはいえ正規表現ってパッと見はなにかの呪文のように見える、、、
しかし少し勉強してみれば、案外読めてしまうものです。
私も本を呼んだりしてもうちょっとちゃんと勉強しなきゃなー、、、