2015/04/04

[Python]続・指定した文字列でフォルダを作成し、指定したURLのファイルをダウンロードし保存する。

 [Python]指定した文字列でフォルダを作成し、指定したURLのファイルをダウンロードし保存する。の最後で「使っていていくつか問題も見つけたので、自分で使う分には不都合ないが、今後修正することも考えたい。」と書いた。
その「問題」を列挙すると、

  • フォルダを作成しようとする際、既に同名フォルダがあるとエラーとなって処理を中止する。
  • フォルダを作成しようとする際、特定の文字が含まれていると「\uff5e」云々のエラーなど、文字コード関連でエラーが出ることがある。
  • そして上述2つのエラーが両方共exceptで拾われる場合があり、どちらのエラーかすぐにはわからない。

列挙する、と言いつつ実質2つしか見つけていないじゃないか!という感じだが、とりあえずこの2点について修正することにした。

 一点目の修正は簡単だ。取得したページタイトルをフォルダ名とするフォルダがあるかを確かめ、あればそのフォルダへ移動し、なければフォルダを作成するようにすればよい。
ということでこうする。

#画像保存フォルダ作成
title = title.encode('cp932')
checkedpath = os.path.join(os.getcwd(), title)
if(os.path.isdir(checkedpath)):
    print u"同名フォルダが既に存在します。"
    print u"該当フォルダにファイルを保存します。同名ファイルがある場合は上書きします。"
    os.chdir(title)
else:
    try:
        os.mkdir(title)
        os.chdir(title)
        print u"フォルダを作成しました。"
    except:
        print u"フォルダを作成できませんでした。ページタイトルを確認して下さい。"
        print u"処理を中止します。"
        sys.exit()

まずは作成しようとするフォルダのパスを os.path.join(os.getcwd(), title)で作成し、checkpathに代入。

if(os.path.isdir(checkedpath))でそのフォルダが存在するかを確認し、あればフォルダへ移動、なければ前回作った部分の処理を実行するようにした。

 これで1つ目の問題、そして3つ目の問題は解消した。この時点でエラーで終了するのは2つ目の問題、文字コード絡みの場合のみといってもいい。
文字コード絡みのエラーは二種類あるようで、ひとつはタイトルにフォルダ名として使えない文字が含まれている場合、そしてもう一つがshift_jisにエンコードできない場合のようだ。
上述の「\uff5e」云々のエラーは後者の場合のメッセージのようだ。
前者はtitleを1文字ずつチェックし、if文なりswitchなりでフォルダ名に使える文字に変換すればよさそうだ、と解決策を考えたところでとりあえず納得した。
問題は後者で、文字コード関連は未だによくわかっていないのでどうすればいいかわからなかった。

素直に「Python \uff5e」で検索すると、こちらのサイトを発見。

というわけで、
title = title.encode('shift_jis')

title = title.encode('cp932')
に代えてみたところ、このエラーを見ることはとりあえずなくなった。

# coding:utf-8
# Project_KAGA

import urllib2
import re
import os
import urllib
import sys

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

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

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

#画像URL検索
img = re.compile("[正規表現]")
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
#重複削除
for i in rowImglist:
    if not i in imglist:
        imglist.append(i)

#記事タイトル取得
titlestart = re.compile("")
titleend = re.compile("")

ts = titlestart.search(html, 0)
te = titleend.search(html,ts.end())

title = html[ts.end() : te.start()]

#タイトル・画像URL出力
print title.decode('utf_8')
for imgurl in imglist:
    print imgurl

#画像保存フォルダ作成
title = title.encode('cp932')
checkedpath = os.path.join(os.getcwd(), title)
if(os.path.isdir(checkedpath)):
    print u"同名フォルダが既に存在します。"
    print u"該当フォルダにファイルを保存します。同名ファイルがある場合は上書きします。"
    os.chdir(title)
else:
    try:
        os.mkdir(title)
        os.chdir(title)
        print u"フォルダを作成しました。"
    except:
        print u"フォルダを作成できませんでした。ページタイトルを確認して下さい。"
        print u"処理を中止します。"
        sys.exit()

#画像ダウンロード
i = 1
for imgurl in imglist:
    savepath = os.path.join(os.getcwd(), os.path.basename(imgurl))
    urllib.urlretrieve(imgurl, savepath)
    print str(i)+u"枚目ダウンロード完了"
    i+=1
print u'ダウンロードが完了しました。'

とりあえずこんな形に。
現状「フォルダを作成できませんでした。ページタイトルを確認して下さい。」というメッセージが出たらまずフォルダ名に使えない文字がページタイトルにある場合だが、このメッセージが出ること自体滅多にないので、とりあえずそちらは放置で。
あとは正規表現を対象のサイトに合わせてどう書くか、というのが問題かな、と。
こればっかりは正規表現に色々触れて慣れるしかないと思った。

0 件のコメント:

コメントを投稿