こんにちは、さすを(@sasuwo0409)です。
いきなりですが、
画像を自動で収集したい!
Pythonを使って形になるものを作ってみたい!
と思ってはいませんか?
今回の記事は、Pythonを使って自動でGoogle画像を収集する方法を解説してみたいと思います。
この記事を読めば、効率的に画像を収集できるようになります。
それでは本文をどうぞ。
画像を大量に集めなきゃいけないんだけど、ひとつひとつ手でやるのめんどくさいのよね、、
もっと効率的に集める方法はないかしら、、
この悩みを解決します!
※0円のサンプルテキストという近道
独学よりプログラミングスクールの方が効果は出やすいですが、値段が高く、なかなか手を出しづらいですよね。techgymでは無料のサンプルテキストと解説動画をもらえるので、これを使ってお得にPythonの基礎を学ぶのもオススメです。
最短1分でできる!
1.Pythonを使って自動でGoogle画像を収集する方法
今回はGoogle Colaboratory上でプログラムを動かしていきます。
Google Colaboratoryの使い方については「【3分で解決!】Google Colaboratoryの使い方【無料ですぐにPythonを使えます】」で解説しています。
Pythonを使って自動でGoogle画像を収集するための手順は以下の3ステップです。
- 画像を格納するフォルダを作成する
- 必要なライブラリをインストールする
- 画像を収集するプログラムを書く
その①:画像を格納するフォルダを作成する
今回は、プログラムが格納されているGoogle Colabフォルダ直下にimgフォルダを作成しています。また、imgフォルダの中にurlフォルダを作っています。
Google Colab
—–get_pic.ipnb(これから作るスクリプト)
—–img
———–url
フォルダ構成を変更してもOKですが、後述するプログラムの保存先フォルダ名が変わるので注意してください。
その②:必要なライブラリをインストールする
プログラムを動かすうえで必要なものが2つあります。以下のコードを実行し、インストールしましょう。
pip install selenium
!apt install chromium-chromedriver
その③:画像を収集するプログラムを書く
Google画像を自動で収集するプログラムは下記の通りです。
#ドライブをマウントする
from google.colab import drive
drive.mount('/content/drive')
補足:
上記のコマンドを実行すると、以下の画面が現れます。手順通りに操作すればOKです。
1.URLを押下
2.希望のアカウントを選択
3.ログインを押下
4.コードをコピーし、「Enter your authorization code」に入力
#カレントディレクトリに移動
%cd "/content/drive/My Drive/Google Colab"
import requests
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import os
import time
import datetime
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import ElementClickInterceptedException
tm_start = time.time() #処理時間計測用
dt_now = datetime.datetime.now() # 現在日時
dt_date_str = dt_now.strftime('%Y/%m/%d %H:%M')
print(dt_date_str)
QUERY = '犬 フリー' # 検索ワード
LIMIT_DL_NUM = 100 # ダウンロード数の上限
SAVE_DIR = 'img/dog_' # 出力フォルダへのパス(フォルダがない場合は自動生成する)
FILE_NAME = 'dog_' # ファイル名(ファイル名の後ろに0からの連番と拡張子が付く)
TIMEOUT = 60 # 要素検索のタイムアウト(秒)
ACCESS_WAIT = 1 # アクセスする間隔(秒)
RETRY_NUM = 3 # リトライ回数(クリック、requests)
DRIVER_PATH = '/usr/bin/chromedriver' # chromedriver.exeへのパス
# Chromeをヘッドレスモードで起動
options = Options()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--start-fullscreen')
options.add_argument('--disable-plugins')
options.add_argument('--disable-extensions')
driver = webdriver.Chrome(DRIVER_PATH, options=options)
# タイムアウト設定
driver.implicitly_wait(TIMEOUT)
tm_driver = time.time()
print('WebDriver起動完了', f'{tm_driver - tm_start:.1f}s')
# Google画像検索ページを取得
url = f'https://www.google.com/search?q={QUERY}&tbm=isch'
driver.get(url)
tm_geturl = time.time()
print('Google画像検索ページ取得', f'{tm_geturl - tm_driver:.1f}s')
tmb_elems = driver.find_elements_by_css_selector('#islmp img')
tmb_alts = [tmb.get_attribute('alt') for tmb in tmb_elems]
count = len(tmb_alts) - tmb_alts.count('')
print(count)
while count < LIMIT_DL_NUM:
# ページの一番下へスクロールして新しいサムネイル画像を表示させる
driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
time.sleep(1)
# サムネイル画像取得
tmb_elems = driver.find_elements_by_css_selector('#islmp img')
tmb_alts = [tmb.get_attribute('alt') for tmb in tmb_elems]
count = len(tmb_alts) - tmb_alts.count('')
print(count)
# サムネイル画像をクリックすると表示される領域を取得
imgframe_elem = driver.find_element_by_id('islsp')
# 出力フォルダ作成
os.makedirs(SAVE_DIR, exist_ok=True)
# HTTPヘッダ作成
HTTP_HEADERS = {'User-Agent': driver.execute_script('return navigator.userAgent;')}
print(HTTP_HEADERS)
# ダウンロード対象のファイル拡張子
IMG_EXTS = ('.jpg', '.jpeg', '.png', '.gif')
# 拡張子を取得
def get_extension(url):
url_lower = url.lower()
for img_ext in IMG_EXTS:
if img_ext in url_lower:
extension = '.jpg' if img_ext == '.jpeg' else img_ext
break
else:
extension = ''
return extension
# urlの画像を取得しファイルへ書き込む
def download_image(url, path, loop):
result = False
for i in range(loop):
try:
r = requests.get(url, headers=HTTP_HEADERS, stream=True, timeout=10)
r.raise_for_status()
with open(path, 'wb') as f:
f.write(r.content)
except requests.exceptions.SSLError:
print('***** SSL エラー')
break # リトライしない
except requests.exceptions.RequestException as e:
print(f'***** requests エラー({e}): {i + 1}/{RETRY_NUM}')
time.sleep(1)
else:
result = True
break # try成功
return result
tm_thumbnails = time.time()
print('サムネイル画像取得', f'{tm_thumbnails - tm_geturl:.1f}s')
# ダウンロード
EXCLUSION_URL = 'https://lh3.googleusercontent.com/' # 除外対象url
count = 0
url_list = []
for tmb_elem, tmb_alt in zip(tmb_elems, tmb_alts):
if tmb_alt == '':
continue
print(f'{count}: {tmb_alt}')
for i in range(RETRY_NUM):
try:
# サムネイル画像をクリック
tmb_elem.click()
except ElementClickInterceptedException:
print(f'***** click エラー: {i + 1}/{RETRY_NUM}')
driver.execute_script('arguments[0].scrollIntoView(true);', tmb_elem)
time.sleep(1)
else:
break # try成功
else:
print('***** キャンセル')
continue # リトライ失敗
# アクセス負荷軽減用のウェイト
time.sleep(ACCESS_WAIT)
alt = tmb_alt.replace("'", "\\'")
try:
img_elem = imgframe_elem.find_element_by_css_selector(f'img[alt=\'{alt}\']')
except NoSuchElementException:
print('***** img要素検索エラー')
print('***** キャンセル')
continue
# url取得
tmb_url = tmb_elem.get_attribute('src') # サムネイル画像のsrc属性値
for i in range(RETRY_NUM):
url = img_elem.get_attribute('src')
if EXCLUSION_URL in url:
print('***** 除外対象url')
url = ''
break
elif url == tmb_url: # src属性値が遷移するまでリトライ
print(f'***** urlチェック: {i + 1}/{RETRY_NUM}')
time.sleep(1)
url = ''
else:
break
if url == '':
print('***** キャンセル')
continue
# 画像を取得しファイルへ保存
ext = get_extension(url)
if ext == '':
print(f'***** urlに拡張子が含まれていないのでキャンセル')
print(f'{url}')
continue
filename = f'{FILE_NAME}{count}{ext}'
path = SAVE_DIR + '/' + filename
result = download_image(url, path, RETRY_NUM)
if result == False:
print('***** キャンセル')
continue
url_list.append(f'{filename}: {url}')
# ダウンロード数の更新と終了判定
count += 1
if count >= LIMIT_DL_NUM:
break
tm_end = time.time()
print('ダウンロード', f'{tm_end - tm_thumbnails:.1f}s')
print('------------------------------------')
total = tm_end - tm_start
total_str = f'トータル時間: {total:.1f}s({total/60:.2f}min)'
count_str = f'ダウンロード数: {count}'
print(total_str)
print(count_str)
# urlをファイルへ保存
path = SAVE_DIR + '/url/' + '_url.txt'
with open(path, 'w', encoding='utf-8') as f:
f.write(dt_date_str + '\n')
f.write(total_str + '\n')
f.write(count_str + '\n')
f.write('\n'.join(url_list))
driver.quit()
実行結果:
機械学習をするなら画像データを水増ししよう
機械学習をするために画像を収集しているのであれば、画像枚数が多ければ多いほど精度はあがりますが、画像枚数を増やすのにも限度はありますよね。
そこで、おすすめなのがデータの水増しです。
ですので、機械学習のために画像を収集しているのであれば、データの水増しをしておきましょう。
画像を反転、グレー画像に変更したソースコードを以下に貼っておくので、活用してください。
#反転画像を保存する処理
import cv2
import os
import time
import datetime
tm_start = time.time() #処理時間計測用
dt_now = datetime.datetime.now() # 現在日時
dt_date_str = dt_now.strftime('%Y/%m/%d %H:%M')
print(dt_date_str)
path = 'img/dog'
files = os.listdir(path)
files_file = [f for f in files if os.path.isfile(os.path.join(path, f))]
for y_pic in files_file:
img = cv2.imread(path + "/" + y_pic)
y = cv2.flip(img,1)
cv2.imwrite(path + "/y_" + y_pic,y)
tm_end = time.time()
print('処理完了')
print('------------------------------------')
total = tm_end - tm_start
total_str = f'トータル時間: {total:.1f}s({total/60:.2f}min)'
print(total_str)
#白黒画像を保存する処理
import cv2
import os
import time
import datetime
tm_start = time.time() #処理時間計測用
dt_now = datetime.datetime.now() # 現在日時
dt_date_str = dt_now.strftime('%Y/%m/%d %H:%M')
print(dt_date_str)
path ='img/dog'
files = os.listdir(path)
files_file = [f for f in files if os.path.isfile(os.path.join(path, f))]
print(files_file)
for y_pic in files_file:
img = cv2.imread(path + '/' + y_pic)
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imwrite(path + '/gray_' + y_pic,img_gray)
tm_end = time.time()
print('処理完了')
print('------------------------------------')
total = tm_end - tm_start
total_str = f'トータル時間: {total:.1f}s({total/60:.2f}min)'
print(total_str)
最後に:機械に働かせて自分は休もう
Google Colaboratoryを使って自動でGoogle画像を収集する方法を解説してきました。
この記事を読んでいるということは、めんどくさい作業を自動化して、自分の時間を生み出そうとしている「時間の大切さを知っている人」だと思います。
『Time is not money(時間はお金では買えない)』
という言葉を忘れずに、これからもコツコツと自分の時間が増えるようプログラムを書いていこうと思います。
この記事が少しでも役に立っていたらうれしいです!
それでは!
参考にした記事:PythonスクレイピングでGoogle画像検索ページから画像を取得
最短1分でできる!
コメント