개발 공부

Python Google image web crawling (구글 이미지 웹크롤링)

준군 2021. 2. 14. 13:51

근 두달만에 글을 올린다.

최근에 딥러닝을 공부를 하느라 개인적인 시간이 부족 했었던 핑계를 대면서...

 

이번글에서는 구글에서 이미지를 다운받는 법을 알아볼 것이다.

저자는 웹크롤링을 그냥 한번 해보고 싶어서 beautifulsoup4이라는 라이브러리를 써서 해보는 유튜브 강의를 보며 해보려 했으나 이상하게도 이미지 20개만 다운로드가 받아져서 손을 보아야했다.

 

그러므로, 이 글의 핵심은 2021-02-14 기준으로 구글의 html 태그 형식을 보고 만든 것이므로 추후에는 동작이 안될 수도 있으나, 이해를 하고 넘어가면 독자들도 충분히 만들수 있으리라 본다.

 

결과

이렇게 특정 검색어를 입력하면

검색어의 결과 이미지를 모두 받는 것이다. (car에 대한 이미지 갯수는 총 826개였다.)

 

 

준비물

import urllib.request
from urllib.parse import quote_plus
from bs4 import BeautifulSoup
from selenium import webdriver
import time

아마 웹크롤링이 처음이라면 BeautifulSoup 과 selenium을 받아줘야 된다.

또한, chrome webdriver라는 것을 찾아서 받아줘야된다.

꼭 본인의 크롬에 맞는 버전을 받아야 된다.

chromedriver.chromium.org/downloads

 

Downloads - ChromeDriver - WebDriver for Chrome

WebDriver for Chrome

chromedriver.chromium.org

 

구현

keyword = input('검색할 태그를 입력하세요 : ')
url = 'https://www.google.com/search?q={}&source=lnms&tbm=isch&sa=X&ved=2ahUKEwjgwPKzqtXuAhWW62EKHRjtBvcQ_AUoAXoECBEQAw&biw=768&bih=712'.format(keyword)

driver = webdriver.Chrome()
driver.get(url)

time.sleep(1)

scroll_down()

html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
images = soup.find_all('img', attrs={'class':'rg_i Q4LuWd'})

print('number of img tags: ', len(images))

n = 1
for i in images:

    try:
        imgUrl = i["src"]
    except:
        imgUrl = i["data-src"]
        
    with urllib.request.urlopen(imgUrl) as f:
        with open('./img/' + keyword + str(n) + '.jpg', 'wb') as h:
            img = f.read()
            h.write(img)

    n += 1

 

큰 흐름은 다른 글들과 비슷하지만, 저자가 수정한 부분을 중점으로 설명하겠다.

 

- images 변수는 img 태그들 중에 class명이 rg_i Q4LuWd인 태그들을 모두 가져오는 것이다.

- imgUrl 변수가 "src" 일때도 있고 "data-src"일 때도 있는데, 현재 구글의 이미지 태그들을 보면 src에 이미지 소스가 담겨 있을 경우도 있고 data-src에 담겨 있을때도 있다.

 

scroll_down 함수

def scroll_down():
    global driver
    last_height = driver.execute_script("return document.body.scrollHeight")

    while True:
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(SCROLL_PAUSE_SEC)
        new_height = driver.execute_script("return document.body.scrollHeight")

        if new_height == last_height:
            time.sleep(SCROLL_PAUSE_SEC)
            new_height = driver.execute_script("return document.body.scrollHeight")

            try:
                driver.find_element_by_class_name("mye4qd").click()
            except:

               if new_height == last_height:
                   break


        last_height = new_height

함수명에서 알수 있듯이 스크롤 다운을 해주는 함수인데 왜 스크롤 다운을 해줘야 될까?

구글 이미지 창을 보면 스크롤 다운을 해주면서 이미지들이 추가적으로 불러와진다.

또한 여기서 time.sleep을 하는 이유는 스크롤 다운을 해도 웹브라우저가 반응을 할 수 있게 기다려주는 시간이다.

또 다른 중점적인 요소는 스크롤을 하다가 show more results 라는 버튼이 아래 생길때가 있는데 이 버튼을 클릭해주면 더 스크롤 다운을 할 수 있는 영역이 생겨난다. 이 부분도 구현해 주었다.