mecobalamin’s diary

人間万事塞翁が馬

ImageNetから画像を一括ダウンロードする

3 November 2020 追記
落としたファイルがESETのウィルススキャンに引っかかた
マルウェアだったっぽい
ファイルのチェックが必要
追記ここまで


機械学習に使う画像を探してみたら
ImageNetに行き着いた
有名なサイトのようだ
image-net.org
starpentagon.net

画像の種類を選んで
画像のURLリストを入手できる
スクレイピングでリストを作成しているらしい

検索かけるとURLを使って画像を
一括ダウンロードするpythonスクリプトが見つかる

ImageNetから画像データをダウンロードする方法 - Murayama blog.
【初心者向け】PythonでURLを指定して画像をダウンロードする - Qiita
PythonでWeb上の画像などのファイルをダウンロード(個別・一括) | note.nkmk.me

画像をダウンロードするスクリプトpythonで作成した
この方のスクリプトをベースにしている
python3のrequestsを使って画像を保存 - Qiita

これはImageNetからダウンロードしたURLのリスト

http://farm2.static.flickr.com/1255/1408362724_60deb2b753.jpg
http://www.autoweek.nl/images/480/e/52e07211aa41ddd948a4fffc8aec126e.jpg
http://farm1.static.flickr.com/25/59557472_761b98f3d9.jpg
http://farm4.static.flickr.com/3291/2680953450_dfab0392cf.jpg
http://farm3.static.flickr.com/2253/2472449713_0c161a43bc.jpg
http://farm4.static.flickr.com/3007/2653464907_8372065990.jpg
以下略

URLは1367行
テキストファイル"ImageURL.txt"として保存する

URLはクローラーで集めているらしく
ブラウザで確かめるとリンク切れがある
サーバーそのものにつながらない場合もある
何かしらファイルは在るけど画像でない場合もある
そういったURLをうまく弾くようにする

HTTPエラーはこの方のスクリプトを参考にして弾いた
requestsを使った画像のダウンロード - Qiita

ファイルが画像でない場合も保存しない
【初心者向け】PythonでURLを指定して画像をダウンロードする - Qiita

手間取ったのはサーバーにつながらない場合
サーバーエラーの場合requests.get()は
connection errorを返してくるらしい
クイックスタート — requests-docs-ja 1.0.4 documentation
Developer Interface — requests-docs-ja 1.0.4 documentation

だがConnectionErrorではうまく例外処理ができなくて
"requests.RequestException"を返してきたときに
例外処理をするようにコードを書いた

    while True:
        try:
            r = requests.get(url, stream=True)
        except requests.RequestException as e:
            print('There was an ambiguous exception that occurred while handling your request.')
            print(e)
            break

例外を表示させてみると
URLによって様々っぽい
これはその一例

http://www.wewantyou.co.nz/images/cartypes/Stationwagon.jpg
There was an ambiguous exception that occurred while handling your request.                             HTTPConnectionPool(host='www.wewantyou.co.nz', port=80): Max retries exceeded with url: /images/cartypes/Stationwagon.jpg (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f3e94f55510>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))

URLは1367行あるが
実際にダウンロードできた画像は656ファイル
ダウンロードしたファイルは
連番のjpg形式で保存する
zfill()は引数の桁に合わせて0詰めをする

実際に使ったコードはこちら

# -*- coding: utf-8 -*-

import requests

# Functions

# Download images
# https://qiita.com/pollenjp/items/0c39c35120cd60575647
def download_img(url, file_name):
    print(url)
    while True:
        try:
            r = requests.get(url, stream=True)
        except requests.RequestException as e:
            print('There was an ambiguous exception that occurred while handling your request.')
            print(e)
            break
        else:
            if r.status_code != 200:
                print("You have an HTTP error in this URL.")
                print("Error Code: " + str(r.status_code))
                break
            elif 'image' not in r.headers["content-type"]:
                print('This is not Image file.')
                break
            else:
                with open(file_name, 'wb') as f:
                    f.write(r.content)
                break

# read URLs
def readFile(FileName):
    with open(FileName, 'r') as file:   # with文で閉じ忘れがない
        lines = file.readlines()        # readlines()で1行毎に読み込み

    URLs = []
    for i in lines:                     # fileの行数分繰り返す
        if not i == "\n":
            URLs.append(i.replace("\n", "")) # 改行コードの削除

    return URLs

# Main
if __name__ == '__main__':
    # Parameters
    URL_List = "ImageURL.txt"

    # Path to files
    Path_WorkingDirectory = '/Path/to/Working/Directory/'
    Path_OutputDirectory = Path_WorkingDirectory + 'DownloadImages/'

    URLs = readFile(URL_List)
    n = 0
    for i in URLs:
        download_img(i, Path_OutputDirectory + 'Car_' + str(n).zfill(5) + '.jpg')
        n = n + 1