2015/03/18

[Python]Webページのタイトル・画像URLを取得する。

 「URLを入力すると、そのページのタイトルでフォルダを作り、その中にそのページに貼られている画像を保存する。」というプログラムを作りたいと思う。
今回は久しぶりにPythonを使って作ることにした。春休みに入ってから全くPythonに触れていなかったので、新学期から再びゼミが始まる前に慣れておきたかったからだ。
この記事ではプログラムの第一段階「Webページタイトル取得と画像URL一覧リストの作成」までを扱うことにする。

 まずはおまじないと今回使うモジュールのインポートを行う。
行う、といいつつこれは完成したプログラムからの抜粋なので、第二段階(次記事以降)で使うモジュールもインポートしている。

# coding:utf-8
import urllib2
import re
import os
import urllib
import sys

まずはURLを入力できるようにする。

#対象URL入力
url = raw_input(u"URLを入力してください。".encode("shift_jis"))

ここでまず詰まった(はやい)。
「URLを入力してください」が文字化けしてしまったのだ。
uを付けてもダメで、色々調べるとencodeだのdecodeだのすれば文字化けがなくなると知った(分かったわけではないのがポイント)。
詳しいことはわからないまま、encodeとdecodeでそれぞれ文字コードを色々試した結果、上記のようにするとエラーが無くなった。

次に、入力したURLとの接続を確立し、ソースを読む。

#URLを開き、ソースを読む。
source = urllib2.urlopen(url)
html = source.read()
source.close()

ここは特に問題なかった。

次にソースから画像URLを保持するリストを作り、ソースから対象の画像URLを抜き出してリストに追加するようにする。

#画像URL格納リスト作成
rowImglist = []
imglist = []

#画像URL検索
img = re.compile("[対象画像URLの正規表現]")
i = 0 while i >= 0:   m = img.search(html, i)   if m:     rowImglist.append(html[m.start():m.end()])     i = m.start()+1   else:     break

[対象画像URLの正規表現]の部分は、対象となるページの画像URLの規則性に合わせて書く必要がある。
必要がある(キリッ、なんて言いつつ以前プログラミングの本を読んだ時に正規表現がよくわからず、「こんなもんわからなくてもヘーキヘーキ」と読み飛ばしたせいでだいぶ苦労した。
今となってみると便利で、かつ奥が深い。
だいたいのサイトは画像の名前付けに規則性があるのでなんとかなると思う。(画像ファイル名以外はだいたい一緒なので、画像ファイル部分を「\w\.jpg」などと書けばいいはず。)
もし全く規則性がない場合は「http://[任意の英数字またはスラッシュ].jpg」を正規表現で表せばいけるのかな、と思うが(未確認)、これだと例えば広告の画像ファイルとかまで拾ってしまうと思う。
これについては今後の課題というやつだ。
対象となる画像URLを検索する部分(while文)についてはこちらのサイトのコードを参考にさせていただいた。

上の部分でrowImglistに正規表現に合致する画像URLが格納されている。
しかし実はこれには問題があって、多くのサイトで画像を画像ファイルへのリンクのaタグでimgタグを挟むという形で、画像ファイルへのリンクと画像ファイルの表示を行っている。
つまりrowImglistには同じ画像ファイルのURLが2つずつ格納されている。
そこで、この重複を

#重複削除
for i in rowImglist:
  if not i in imglist:
    imglist.append(i)

で取り除く。imglistには重複のない画像URLが格納されている。

次にWebページのタイトルを取得する。

#記事タイトル取得
titlestart = re.compile("")
titleend = re.compile("")
ts = titlestart.search(html, 0)
te = titleend.search(html,ts.end())
title = html[ts.end() : te.start()]

ページのタイトルは1つしかないので先ほどのような繰り返しは必要ない。
まず「"<title>"」を検索、次に「"</title>"」を検索。
これらの間にある文字列がWebページのタイトルとなるので、ソースのts.end()文字目からte.start()文字目がWebページのタイトル、というわけだ。
Pythonの文字列のインデックスはちょっとクセがあって少し悩んだが、これで上手く動いているのでまあ問題ないだろう。

これでtitleにはWebページのタイトルが、imglistにはそのページに貼られている画像のURLが格納されている状態になった。
次記事以降でフォルダをtitleという名前で作成し、その中にimglistにある画像をダウンロードする部分を作成する。

0 件のコメント:

コメントを投稿