[파이썬] 구글 이미지 다운로드 프로그램(수정-12/5/20)
프로젝트/파이썬

[파이썬] 구글 이미지 다운로드 프로그램(수정-12/5/20)

요즘 구글의 Teachable Machine에 관심이 생겨서 여러 가지를 실험해보려고 했는데....

사진 모으는게 겁나 귀찮습니다

그래서 구글 이미지에서 자동으로 이미지를 다운로드해주는 프로그램을 만들었습니다.

원래는 적당한 게 있나 찾아보려고 했는데

다 옛날 거라 구글처럼 웹사이트가 자주 바뀌면 쓸 수가 없더라고요.(찾아본것중 절반이 클래스명이 다름)

사실 google-image-download라는 파이썬 모듈이 있습니다만 내친 김에 공부도 할 겸 직접 만들었습니다

 

알아야 하는 것들:

파이썬, 셀레니움, HTML

 

일단 코드는 다음과 같습니다:

from requests import get
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep
import os
from tkinter import Tk
from tkinter.simpledialog import askstring
from shutil import copyfileobj
from base64 import b64decode

window = Tk()
# 유저가 입력한 키워드들을 리스트로 저장
keyword_list = askstring(
    title='구글 이미지 다운로더', prompt='검색할 키워드를 콤마(,)로 구분해주세요(키워드가 두단어 이상이라면 공백으로 구분하세요').split(',')
window.destroy()
PATH = './chromedriver'
# 크롬을 띄우지 않는 옵션 설정
options = webdriver.ChromeOptions()
options.headless = True
try:
    driver = webdriver.Chrome(PATH, options=options)
    # 키워드 별로 반복문을 돌림
    for keyword in keyword_list:
        # 구글의 키워드 검색결과의 이미지 탭으로 가는 링크
        url = '''https://www.google.com/search?tbm=isch&source=hp&biw=&bih=&ei=0VgdX4viLcq9hwOB7IngCQ&q=''' + keyword.strip()
        driver.get(url)
        # 폴더가 없으면 키워드로 폴더를 만듦
        try:
            parent_dir = "./images/"
            path = os.path.join(parent_dir, keyword)
            os.mkdir(path)
            print('Path made for ' + keyword)
        except:
            print('Directory already exists for keyword:', keyword)
        # 페이지가 로딩이 느릴 때를 대비해 5초를 기다림
        sleep(5)
        # 다음 페이지의 가장 밑까지 가게한다
        last_height = driver.execute_script('return document.body.scrollHeight')
        while True:
            driver.execute_script(
                'window.scrollTo(0,document.body.scrollHeight)')
            sleep(1)
            new_height = driver.execute_script(
                'return document.body.scrollHeight')
            if new_height == last_height:
                # 이미지를 더 로딩하는 버튼을 누름
                try:
                    driver.find_element_by_class_name('mye4qd').click()
                    sleep(1)
                except:
                    break
            last_height = new_height
        print('Done scrolling')
        # 페이지 내 모든 이미지를 찾음
        image_urls = driver.find_elements_by_css_selector('img.rg_i.Q4LuWd')
        print('Found', len(image_urls), 'results')
        count = 1
        for image_thumbnail in image_urls:
            # 원본 이미지를 다운로드하기 위해 썸네일을 클릭함
            ActionChains(driver).click(image_thumbnail).perform()
            sleep(2)
            # 같은 클래스를 가진 이미지가 여러개이기 때문에 xpath를 통해 지정함
            image_url = driver.find_element_by_xpath(
                '/html/body/div[2]/c-wiz/div[3]/div[2]/div[3]/div/div/div[3]/div[2]/c-wiz/div/div[1]/div[1]/div/div[2]/a/img').get_attribute("src")
            with open(f'./images/{keyword}/{count}.jpg', 'wb') as image_file:
                # 이미지가 base64로 인코딩된 텍스트일때
                if image_url.startswith('data:image/jpeg;base64,'):
                    # 이미지 데이터를 디코딩해 저장한다(데이터를 해석해 저장)-23번째 인덱스부터 시작한다.
                    image_file.write(b64decode(image_url[23:]))
                else:  이미지의 소스가 링크일때
                    # requests.get 함수를 사용해 링크에서 이미지(와 기타 등등)을 가져온다-stream은 안정성을 위해 추가
                    response = get(image_url, stream=True)
                    # 이미지 데이터를 열고있는 파일에 저장한다.
                    copyfileobj(response.raw, image_file)
                    # 버퍼를 없앤다
                    del response
                count += 1
        print('Done scrapping images')
finally:
    # 브라우저를 닫고 더 이상의 셀레니움을 사용한 코드 실행을 멈춤
    driver.quit()

 

수정사항:

찾는 이미지는 400개지만 실제 다운로드는 200~300인 것(수정됨)

해당 프로그램을 사용하려면 실행 후 가만히 놔두고 멈추기까지 기다려야 모든 결과를 얻을 수 있다.

해당 이미지의 원본을 긁어오는 것이 아닌 구글의 썸네일(?) 수준으로 가져오기에 화질이 좋지 않다.(300p 정도)(수정됨)

시작에 tkinter를 사용해 간단한 GUI를 만들었습니다.

Headless Chrome을 통해 크롬이 켜지지 않고 이미지를 다운로드할 수 있게 업데이트했습니다.

- tk 창 하나가 뜨는데 무시하고 다른 일 하시면 됩니다.

깃허브