読者です 読者をやめる 読者になる 読者になる

ami_GS's diary

情報系大学院生の備忘録。ネットワークの勉強にハマっています。

BeautifulSoup4 で画像ダウンロードしてみた

BeautifulSoup スクレイピング Python

「このページにある画像一式ダウンロードしたいなー」
と思う時のためのプログラムを書いてみた

簡単に説明すると、

  1. urllib2で、目的とするページのソースをダウンロード
  1. BeautifulSoup4でimgタグのsrcから画像URLを抽出
  1. urllibで画像URL先のデータをダウンロード

という感じ。
1年ぶりにBeautifulSoup使ってみたけど、BeautifulSoup4が出て微妙に文法変わったらしい。

以下、ソースコード



import os

def rmQ(fname):
    return fname.split("?")[0] #保存するファイル名から「?」以下を削除

def getImgURL(src, url):
    if "http" not in src:
        return url+src #他ページからのリンクに対応
    else:
        return src

def mkdir(dirName):
    try:
        os.mkdir(dirName) #ディレクトリ作成
    except Exception as e:
        print e
#        pass # if dirName already exist

def DLImages(AllImages, url, dirName):
    import urllib

    successNum = 0
    for img in AllImages:
        src = img.get("src") #imgタグのsrcを取得
        imgURL = getImgURL(src, url)
        fname = src.split("/")[-1]

        if "?" in fname:
            fname = rmQ(fname)
        try:
            if fname in os.listdir(dirName):
                fname = fname + str(successNum)
            urllib.urlretrieve(imgURL, dirName+"/"+fname) #作成したディレクトリに保存
            print "[ Success ] " + imgURL
            successNum += 1
        except Exception as e:
            print e
            print "[ Failed ] " + imgURL        

    return successNum #ダウンロード成功の数を返す

def main(url, dirName="./DLImages"):
    from bs4 import BeautifulSoup
    import urllib2
    
    mkdir(dirName)
    response = urllib2.urlopen(url) #ページオープン
    html = response.read() #html取得
    soup = BeautifulSoup(html)
    AllImages = soup.find_all("img") #全imgタグを取得
    imgNum = len(AllImages)
    successNum = DLImages(AllImages, url, dirName)

    print successNum, "images could be downloaded (in", imgNum, "images)."

if __name__ == "__main__":
    import sys
    if len(sys.argv) == 2:
        main(sys.argv[1])
    elif len(sys.argv) == 3:
        main(sys.argv[1], sys.argv[2])

関数を小分けにしてモジュールインポートをその中で行う手法をやってみた。(見にくいかもしれない)

この
画像で吹いたら寝ろ : スコールちゃんねる ~2ちゃん おもしろ ニュース~
ページで実験した結果がこちら
f:id:ami_GS:20140217203847p:plain

う〜〜〜〜〜〜ん、、、
.phpとか無名のファイルがありますな・・・



こちら
【画像】吹いた画像まとめ - NAVER まとめ
で実験したところ、クエリ文字列より前が拡張子を持たないため、落とした画像が壊れたように見える。
このページは画像の名前が全て同じなため、名前の後に数字をつけるようにした。
壊れているように見えるが開く事は可能である。

githubami-GS/DLWebImages · GitHubで直して行こうと思う。(今日は疲れた)