画像のURL抽出を通して正規表現を勉強してみた
今まで正規表現というものに対して、ネットのコピペでやり過ごしていました。
ただそれでは流石にまずいな、と思い勉強をしてみました。
何か目的がないと作っていても楽しくないので、rubyで画像を収集するクローラーっぽいものを作ることにしました。
今回は、画像のURLを取得した正規表現周りのみについて書きます。
画像の行を探す
まずは、指定したURLのページのソースを一行ずつ読み込み、画像(jpeg,jpg,png,gif)についての記述があるか正規表現で探しました。
line = line.match( /.+(jpeg|jpg|png|gif).+/ )
lineには、ページのソースの一行が入っているとします。
正規表現の構文(以下のURL)を参考にすると
https://msdn.microsoft.com/ja-jp/library/cc392020.aspx
「.」は、任意の一文字
「+」は、直前のサブ式(今回は文字と考えて問題ありません)を1回以上繰り返す
「x|y」は、xまたはyに一致する
つまり「何かしらの文字を繰り返した後に、画像の拡張子があり、再び文字が繰り返す」というものです。
これで画像があるソースの行の取得ができました。
画像のある行から画像のURLのみを取得
今回は以下のlineに以下のような行が代入されたと仮定して、話を勧めます。
<meta itemprop="image" content="https://blog.st-hatena.com/images/theme/og-image-1500.png"/>
このようなHTMLのコードから、pngのURLのみを取得したいと思います。
画像のURLは文字列ですので、「"」で囲まれています。
「"」で囲まれているものを抽出して画像のURLを取得したいのですが、今回の場合は「itemprop」があるように色々と余分なものが入っている場合があります。
そのため、まずは空白や「;」「(」など色々なものを削除する作業をします。
array = line.to_s.split(/[ ()<>;,]/)
正規表現では「[ ]」は、角かっこで囲まれた文字の中のいずれかに一致
そのため、「空白,()<>;,」というコードの切れる部分を全部切るということをします。
そうするとarrayはカットされた結果の配列になります。
arrayの中身は以下のようになります。
[0]:(「<」で切ったため空です) [1]:meta [2]:itemprop="image" [3]:content="https://blog.st-hatena.com/images/theme/og-image-1500.png"/
いい感じになっていきましたね!
ただ今回の場合は文字の最後に「/」が入ったように、何かしらのゴミが入る場合があります。
この配列の中身を一つ一つ確認し文字だけ取得するために、先ほど言った「"」で囲まれているものを抽出します。
array.each do |cut| image_url = cut.to_s.match(/".+(\.jpeg|\.jpg|\.png|\.gif).*"/) end
image_urlの中身は以下のようになります
"https://blog.st-hatena.com/images/theme/og-image-1500.png"
これで「"」に囲まれていますが、画像のURLのみ抽出できました。
あとは最初と最後の文字をカットすると、画像のURLのみとなります。
最後は力技になってしまいましたが、正規表現のいい勉強になりました。
(実行環境)
Ruby