
Rubyでどう書く?:Rubyで特定URLの画像パス一覧を表示する
問題
あるWebサイトをブックマークする際に、そのURLで表示されている画像の一覧から1つの画像を選択した上でブックマークしたいという要望を受け取ったとします。
そこで、画像選択用のサムネイル表示のために、URL上に表示されている画像URLの一覧を配列として提供したいのですが、どのようなメソッドで提供すべきでしょうか?
ここでは、ごく簡単ではありますが正規表現を使って画像URL一覧の取得を行ってみます。
仕様
- 画像ファイルは「jpg, jpeg, gif, bmp, png」を取得する
- URIスキームが「http」の場合のみ画像を取得する
回答例
require 'open-uri' require 'resolv-replace' require 'timeout' class ImageUrl # 特定のURL上の画像パス一覧を取得する def self.get_image_urls(url) begin timeout(1) { begin uri = URI(url) if uri.scheme == "http" #httpsでは画像を取ってこない。 tmp_images = uri.read.scan(/img.+src=[\"|\']?([\-_\.\!\~\*\'\(\)a-zA-Z0-9\;\/\?\:@&=\$\,\%\#]+\.(jpg|jpeg|png|gif|bmp))/i) images = [] tmp_images.each { |img| images << URI.join(url, img[0]) } images.uniq end rescue => exception case exception when OpenURI::HTTPError # 404エラー puts "ページが見つかりません。" when URI::InvalidURIError # 入力エラー puts "URLが入力されていません。" # 他にもエラークラス別に処理を加えるなら以下のように追加 # when エラークラス名 # エラー時の処理 else # その他のエラー puts exception.to_s + "(#{exception.class})" end end } rescue TimeoutError # Timeout時の処理 puts "読み込みに時間がかかりすぎたため、処理を終了しました。" end end end image_urls = ImageUrl.get_image_urls(ARGV[0]) puts image_urls
試しにYahoo!JAPANから画像URL一覧を取得してみましょう。
ruby image_url.rb "http://yahoo.co.jp/"
本記事を執筆時点では、実行結果は以下のようになります。
http://k.yimg.jp/images/clear.gif http://k.yimg.jp/images/top/sp/cgrade/logo.gif http://k.yimg.jp/images/top/searchbox/s_p.gif http://k.yimg.jp/images/new2.gif http://k.yimg.jp/images/top/calender2.gif http://k.yimg.jp/images/top/sp/cgrade/icon_point.gif http://k.yimg.jp/images/top/sp/cgrade/icon_login.gif http://k.yimg.jp/images/premium/top2/cam_searchpoint_50x50_01.gif http://k.yimg.jp/images/top/sp/qr.gif http://k.yimg.jp/images/top/sp/cgrade/dot.gif http://k.yimg.jp/images/mlb/y_top/matsuzaka_02.jpg
解説
本サンプルプログラムでは、以下の順序で処理を実行しています。
1.URL読み込み
ruby1.8.2からは、URI.parse("http://...")をURI("http://...")と書けるようになっているため、後者の書き方に合わせました。
2.URIスキーム判定
URIスキームがhttpの場合のみ画像を抽出したいので、判定文を加えました。open-uriはSSLで自己証明証を使用しているURLにはアクセスできないため、残念ながらhttpsは該当URIスキームからは外しました。
3.読み込んだソースから正規表現で画像URI抽出
正規表現により正しい画像URLのみを抽出します。
4.重複削除し、値を返す
URLによっては同じ画像を何度も呼んでいる場合があるので、Array#uniqで画像パスの重複したものを削除した後に、値を返します。
また、本プログラム作成時に以下の二点に気を付けました。
1.正規表現にオプション「i」をつける
読み込むソースによっては、タグ・属性・拡張子が大文字で記述されている可能性があるので、大文字小文字を無視するオプションが必要になります。
2.エラー(URL未入力、404、タイムアウト)への対処
例として、URLの入力が無かった場合、404レスポンスが返ってきた場合、タイムアウトの場合の三通りについて、個別の対応ができるように記述しました。ここでは、TimeoutErrorはStandardErrorのサブクラスではないため、rescueの際にはクラス名を明記しておく必要があることに注意してください。
個人的な感想ですが、以下の点について工夫を加えれば本プログラムが改善できそうだと思いました。
1.画像URL取得に用いる正規表現
よりスマートな正規表現に書き換えれば、理解しやすく変更も加えやすくなると思います(正直なところ、あまりきれいな正規表現では無いと思っています。申し訳ありません)。
2.CSS(スタイルシート)に記述されている画像URLの取得
本サンプルプログラムでは、CSSに記述されている画像URLの取得までは網羅していません。
3.エラー処理
本プログラムではエラーの種類による分岐までに留めていて、実際の処理に関しては記述しませんでした。要件によって、処理を書き加えるとよいでしょう。
4.httpsへの対応
httpsのページであっても画像が取得できるように変えたほうが、本プログラムをより多くのページで利用できるでしょう。net/httpsを用いれば実現可能なようです。
最後に――
簡単な問題・例文ではありましたが、いかがでしたでしょうか。
本記事では、あるWebサイト上で用いられている画像のURL一覧を取得するという題目でご説明させていただきました。拙作ではありますが、少しでも皆さんのRubyへの理解の助けになれば幸いです。
もっと良い書き方・方法があれば、コメントやbuilderブログなどで教えていただきたいと思います。
- 新着記事
- 特集
- ブログ
- 企画特集
-
特集:IT最適化への道
-
利便性とセキュリティの両立
-
いまあるデータで身近な業務をDX
-
内部不正や不注意をどう防ぐ?
-
連載!プロが語るストレージ戦略
-
IDaaSって何?
-
いまさら聞けない「PPAP」
-
ビッグデータ最前線!
-
セキュリティの今を知る
-
デジタルを当たり前と言えるか?
-
連載!プロが語るストレージ戦略
-
講演の見どころを紹介
-
モバイルデバイスもターゲットに!
-
いままさに社会にとっての転換点
-
データの散在と非常率運用がネック
-
次の一手はこれだ!
-
ゼロトラストに不可欠なID管理
-
請求書がきてからでは遅い
-
保育業界のDX(後編)
-
企業DXのキモはクラウドにあり
-
連載!プロが語るストレージ戦略
-
保育業界のDX(前編)
-
明日からではもう遅い?!
-
さあ、クラウドで解決しよう。
-
話題のセキュリティ事故体験ゲーム