본문 바로가기
Python/Selenium & 크롤링

[python] 3/3__Selenium을 이용한 구글 검색 이미지 크롤링 하기

by 여비코기 2021. 5. 11.

이전 글에 이어 마지막으로 구글 검색 결과의 썸네일 이미지가 아닌, 클릭했을때 나타나는 원본 이미지 파일을 저장해보고자 한다.

 

이전 게시글 1번 : yobbicorgi.tistory.com/29

 

[python] 1/3__Selenium을 이용한 구글 검색 이미지 크롤링 하기

Python Selenium을 이용하여 구글(Google)에서 이미지를 검색한 후, 검색 목록에 나오는 썸네일 이미지들을 모아 다운로드 해보고자 한다. 해당 게시글은 3개의 시리즈로 게시될 예정이며, 시리즈 별

yobbicorgi.tistory.com

이전 게시글 2번 : yobbicorgi.tistory.com/30

 

 

앞선 두번째 게시글과 전체적인 과정은 모두 같다. 하지만 중간에 각 이미지들을 한번 클릭하고, 원본이미지 링크들을 수집하여 모두 저정한 후 다운로드 받는 과정이 추가되었다.

 

1. 필요 모듈 import

from selenium import webdriver 
from selenium.webdriver.common.keys import Keys
import time
import os
import urllib.request
from multiprocessing import Pool
import pandas as pd

이전 방법과 크게 다르지 않으나 multiproccesing을 위한 Pool과 텍스트파일을 이용하기 위한 pandas가 추가되었다.

 

2. 키워드 호출

key=pd.read_csv('./keyword.txt',encoding='cp949',names=['keyword'])
keyword=[]
[keyword.append(key['keyword'][x]) for x in range(len(key))]

keyword라는 텍스트 파일에 나는 다음과 같은 8개의 키워드를 입력하였으며, 이를 각각 검색어로 이용할 것이다.

주걱
도마

가위
접시

그릇
세제

 

3. 폴더 형성 및 이미지 다운로드

def createFolder(directory):
    try:
        if not os.path.exists(directory):
            os.makedirs(directory)
    except OSError:
        print ('Error: Creating directory. ' +  directory)

 

def image_download(keyword):
    createFolder('./'+keyword+'_high resolution')
    
    chromedriver = 'C://chromedriver.exe'
    driver = webdriver.Chrome(chromedriver)
    driver.implicitly_wait(3)
    
    print(keyword, '검색')
    driver.get('https://www.google.co.kr/imghp?hl=ko')
    
    Keyword=driver.find_element_by_xpath('//*[@id="sbtc"]/div/div[2]/input')
    Keyword.send_keys(keyword)
    
    driver.find_element_by_xpath('//*[@id="sbtc"]/button').click()
    
    print(keyword+' 스크롤 중 .............')
    elem =  driver.find_element_by_tag_name("body")
    for i in range(60):
        elem.send_keys(Keys.PAGE_DOWN)
        time.sleep(0.1)
        
    try:
        driver.find_element_by_xpath('//*[@id="islmp"]/div/div/div/div[1]/div[4]/div[2]/input').click()
        for i in range(60):
            elem.send_keys(Keys.PAGE_DOWN)
            time.sleep(0.1)
    except:
        pass
    
    images = driver.find_elements_by_css_selector("img.rg_i.Q4LuWd")
    print(keyword+' 찾은 이미지 개수:',len(images))
    
    links=[]
    for i in range(1,len(images)):
        try:
            driver.find_element_by_xpath('//*[@id="islrg"]/div[1]/div['+str(i)+']/a[1]/div[1]/img').click()
            links.append(driver.find_element_by_xpath('//*[@id="Sva75c"]/div/div/div[3]/div[2]/c-wiz/div/div[1]/div[1]/div/div[2]/a/img').get_attribute('src'))
            driver.find_element_by_xpath('//*[@id="Sva75c"]/div/div/div[2]/a').click()
            print(keyword+' 링크 수집 중..... number :'+str(i)+'/'+str(len(images)))
        except:
            continue

    forbidden=0
    for k,i in enumerate(links):
        try:
            url = i
            start = time.time()
            urllib.request.urlretrieve(url, "./"+keyword+"_high resolution/"+keyword+"_"+str(k-forbidden)+".jpg")
            print(str(k+1)+'/'+str(len(links))+' '+keyword+' 다운로드 중....... Download time : '+str(time.time() - start)[:5]+' 초')
        except:
            forbidden+=1
            continue
    print(keyword+' ---다운로드 완료---')
    
    driver.close()

 

 

여기서 살펴보아야 할 바뀐점은 다음 부분이다

    links=[]
    for i in range(1,len(images)):
        try:
            driver.find_element_by_xpath('//*[@id="islrg"]/div[1]/div['+str(i)+']/a[1]/div[1]/img').click()
            links.append(driver.find_element_by_xpath('//*[@id="Sva75c"]/div/div/div[3]/div[2]/c-wiz/div/div[1]/div[1]/div/div[2]/a/img').get_attribute('src'))
            driver.find_element_by_xpath('//*[@id="Sva75c"]/div/div/div[2]/a').click()
            print(keyword+' 링크 수집 중..... number :'+str(i)+'/'+str(len(images)))
        except:
            continue

    forbidden=0
    for k,i in enumerate(links):
        try:
            url = i
            start = time.time()
            urllib.request.urlretrieve(url, "./"+keyword+"_high resolution/"+keyword+"_"+str(k-forbidden)+".jpg")
            print(str(k+1)+'/'+str(len(links))+' '+keyword+' 다운로드 중....... Download time : '+str(time.time() - start)[:5]+' 초')
        except:
            forbidden+=1
            continue

구글 이미지 검색 결과

구글 이미지 검색 결과에서 원본 이미지를 얻기 위해서는 위와 같이 썸네일 이미지를 클릭하여 오른쪽 창에 뜨는 원본 이미지의 url을 불러와야 고해상도 이미지의 저장이 가능하다.

또한, 이미지의 url을 불러올 때 금지되어있거나, 허용하지 않는 경우도 있기 때문에 forbidden 경고가 뜰 경우 이미지 저장시에 해당 번호는 생략하고 하나씩 앞으로 당겨 저장하도록 하였다.

ex) image_0, image_1, image_3, image_4 (image_2 -> forbidden) X

    image_0, image_1, image_2, image_3 O

 

 

따라서, 스크롤이 모두 끝난 후 각 이미지를 클릭, src의 url을 복사 및 저장, 오른쪽 창 닫기를 반복하여 검색결과의 끝까지 url을 모두 저장 한 후 한번에 이미지를 다운받게 된다.

이 방법의 장점은 고화질의 원본 이미지를 다운받을 수 있지만, 한번씩 이미지를 키고 닫으며 링크를 저장해야하기 때문에 기존 방법보다 시간은 조금 더 걸린다는 단점이 있다.

 

4. Multiprocessing 적용

if __name__=='__main__':
    pool = Pool(processes=4)
    pool.map(image_download, keyword)

processes=4로 설정하여 한번에 최대 4개 창을 동시에 활용할 수 있도록 적용하였다.

 

나는 해당 py파일을 img_down_high_slow.py로 저장하였다.

5. 실행

Anaconda Prompt상에서 py 파일이 존재하는 경로로 이동하여 img_down_high_slow.py 파일을 실행시켜 준다,

python img_down_high_slow.py

 

keyword 파일의 앞선 4개의 keyword 검색 시작
클릭하며 원본 이미지 url을 수집하는 중

이후 link 수집이 완료된 후 원본 이미지들이 각 키워드 폴더로 다운로드되어 저장된다.

 

 

#작동 영상

 

 

 

#full code

from selenium import webdriver 
from selenium.webdriver.common.keys import Keys
import time
import os
import urllib.request
from multiprocessing import Pool
import pandas as pd

key=pd.read_csv('./keyword.txt',encoding='cp949',names=['keyword'])
keyword=[]
[keyword.append(key['keyword'][x]) for x in range(len(key))]


def createFolder(directory):
    try:
        if not os.path.exists(directory):
            os.makedirs(directory)
    except OSError:
        print ('Error: Creating directory. ' +  directory)

def image_download(keyword):
    createFolder('./'+keyword+'_high resolution')
    
    chromedriver = 'C://chromedriver.exe'
    driver = webdriver.Chrome(chromedriver)
    driver.implicitly_wait(3)
    
    print(keyword, '검색')
    driver.get('https://www.google.co.kr/imghp?hl=ko')
    
    Keyword=driver.find_element_by_xpath('//*[@id="sbtc"]/div/div[2]/input')
    Keyword.send_keys(keyword)
    
    driver.find_element_by_xpath('//*[@id="sbtc"]/button').click()
    
    print(keyword+' 스크롤 중 .............')
    elem =  driver.find_element_by_tag_name("body")
    for i in range(60):
        elem.send_keys(Keys.PAGE_DOWN)
        time.sleep(0.1)
        
    try:
        driver.find_element_by_xpath('//*[@id="islmp"]/div/div/div/div[1]/div[4]/div[2]/input').click()
        for i in range(60):
            elem.send_keys(Keys.PAGE_DOWN)
            time.sleep(0.1)
    except:
        pass
    
    images = driver.find_elements_by_css_selector("img.rg_i.Q4LuWd")
    print(keyword+' 찾은 이미지 개수:',len(images))
    
    links=[]
    for i in range(1,len(images)):
        try:
            driver.find_element_by_xpath('//*[@id="islrg"]/div[1]/div['+str(i)+']/a[1]/div[1]/img').click()
            links.append(driver.find_element_by_xpath('//*[@id="Sva75c"]/div/div/div[3]/div[2]/c-wiz/div/div[1]/div[1]/div/div[2]/a/img').get_attribute('src'))
            driver.find_element_by_xpath('//*[@id="Sva75c"]/div/div/div[2]/a').click()
            print(keyword+' 링크 수집 중..... number :'+str(i)+'/'+str(len(images)))
        except:
            continue

    forbidden=0
    for k,i in enumerate(links):
        try:
            url = i
            start = time.time()
            urllib.request.urlretrieve(url, "./"+keyword+"_high resolution/"+keyword+"_"+str(k-forbidden)+".jpg")
            print(str(k+1)+'/'+str(len(links))+' '+keyword+' 다운로드 중....... Download time : '+str(time.time() - start)[:5]+' 초')
        except:
            forbidden+=1
            continue
    print(keyword+' ---다운로드 완료---')
    
    driver.close()
    
# =============================================================================
# 실행
# =============================================================================
if __name__=='__main__':
    pool = Pool(processes=4) # 4개의 프로세스를 사용합니다.
    pool.map(image_download, keyword)

댓글