python/crawling

[Python] Selenium을 사용한 네이버 이미지 크롤링

danuri 2021. 9. 8. 00:46

 

진행 중인 프로젝트에서 음식 이미지를 사용할 일이 있어서 이미지 크롤링에 대해 찾아보기 시작했다.

여러 사이트를 뒤져봤는데, 그 중 네이버 이미지에는 CCL 상업적 이용 가능 옵션이 있어서 보다 안전하게 프로젝트에 사용할 수 있지 않을까 싶어서 네이버에서 크롤링을 하기로 했다.

 

 

구글링을 열심히 해서 여러 크롤링 코드들을 참고했지만, 실제로 잘 동작하지 않아서.... 직접 참고한 몇몇 코드를 따와서 재구성해보았다.

 

일단 beatifulsoup으로 크롤링을 시도했을 때는 특정 태그부터는 parser가 접근을 하지 못해서 (해당 태그에 dataGroupKey 같은 인증 관련된 부분이 있었는데 이 문제인듯 싶다...) selenium을 통해 구현하기로 했다.

 

selenium 설치

우선 selenium 사용을 위해 터미널에 다음 명령어를 입력해준다.

pip install selenium

 

chrome driver 설치

다음은 google Chrome Driver를 설치해 주어야 한다.

https://sites.google.com/a/chromium.org/chromedriver/downloads

 

Downloads - ChromeDriver - WebDriver for Chrome

WebDriver for Chrome

sites.google.com

 

이 사이트에 들어가서 자신의 chrome과 맞는 버전을 다운받아야 한다.

 

+) chrome 버전은 chrome 브라우저 오른쪽 끝에 더보기 -> 도움말 -> Chrome 정보를 통해 확인할 수 있다.

 

 

설치를 완료했으면 자신의 PATH 디렉토리 하위에 chromedriver을 위치시킨다. 이렇게 하면 이후 다양한 프로젝트에서 드라이버를 호출할 때 유용하기에 권장하는 방법이다.

나의 경우는 python, pip 등의 명령어가 모여있는 /usr/local/bin 디렉토리로 chromedriver를 이동시켰다.

sudo mv {.../chromdriver} /usr/local/bin  # 설치한 chromedriver 경로 -> /usr/local/bin

여기까지 진행했으면 기본 세팅은 끝났다.

 

 

코드

<전체 코드>

from selenium import webdriver
from urllib.parse import quote_plus
from urllib.request import urlopen
import os


def save_images(images, save_path):
    for index, image in enumerate(images[:10]):  # images[:크롤링하고 싶은 사진 개수]
        src = image.get_attribute('src')
        t = urlopen(src).read()
        file = open(os.path.join(save_path, str(index + 1) + ".jpg"), "wb")
        file.write(t)
        print("img save " + save_path + str(index + 1) + ".jpg")


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


def make_url(search_term):
    # 네이버 이미지 검색
    base_url = 'https://search.naver.com/search.naver?where=image&section=image&query='
    # CCL 상업적 이용 가능 옵션
    end_url = '&res_fr=0&res_to=0&sm=tab_opt&color=&ccl=2' \
              '&nso=so%3Ar%2Ca%3Aall%2Cp%3Aall&recent=0&datetype=0&startdate=0&enddate=0&gif=0&optStr=&nso_open=1'
    return base_url + quote_plus(search_term) + end_url


def crawl_images(search_term):
    # URL 생성
    url = make_url(search_term)

    # chrome 브라우저 열기
    browser = webdriver.Chrome('chromedriver')
    browser.implicitly_wait(3)  # 브라우저를 오픈할 때 시간간격을 준다.
    browser.get(url)

    # 이미지 긁어오기
    images = browser.find_elements_by_class_name("_image")

    # 저장 경로 설정
    save_path = "/Users/danuri/Desktop/images/" + search_term + "/"
    create_folder_if_not_exists(save_path)

    # 이미지 저장
    save_images(images, save_path)

    # 마무리
    print(search_term + " 저장 성공")
    browser.close()


if __name__ == '__main__':
    crawl_images(input('원하는 검색어: '))

 

함수로 분리해서 그렇지 복잡한 코드는 아니다. 아래서부터 위로 올라가면서 알아보자.

 

<main>

if __name__ == '__main__':
    crawl_images(input('원하는 검색어: '))

프로그램 시작 시 원하는 검색어를 입력해서 이미지 크롤링을 시작한다.

 

<이미지 크롤링>

def crawl_images(search_term):
    # URL 생성
    url = make_url(search_term)

    # chrome 브라우저 열기
    browser = webdriver.Chrome('chromedriver')
    browser.implicitly_wait(3)  # 브라우저를 오픈할 때 시간간격을 준다.
    browser.get(url)

    # 이미지 긁어오기
    images = browser.find_elements_by_class_name("_image")

    # 저장 경로 설정
    save_path = "/Users/danuri/Desktop/images/" + search_term + "/"
    create_folder_if_not_exists(save_path)

    # 이미지 저장
    save_images(images, save_path)

    # 마무리
    print(search_term + " 저장 성공")
    browser.close()

이미지를 크롤링하는 중심 함수다. 위에서부터 알아보자.

 

 

1. URL 생성

url = make_url(search_term)

def make_url(search_term):
    # 네이버 이미지 검색
    base_url = 'https://search.naver.com/search.naver?where=image&section=image&query='
    # CCL 상업적 이용 가능 옵션
    end_url = '&res_fr=0&res_to=0&sm=tab_opt&color=&ccl=2' \
              '&nso=so%3Ar%2Ca%3Aall%2Cp%3Aall&recent=0&datetype=0&startdate=0&enddate=0&gif=0&optStr=&nso_open=1'
    return base_url + quote_plus(search_term) + end_url

네이버 이미지 검색 URL +  검색어(search_term) + CCL 상업적 이용 가능 옵션을 이어서 크롤링하고자 하는 URL로서 사용한다.

 

 

2. chrome 브라우저 열기

browser = webdriver.Chrome('chromedriver')
browser.implicitly_wait(3)  # 브라우저를 오픈할 때 시간간격을 준다.
browser.get(url)

- webdriver.Chrome('chromedriver'): 아까 설치한 chromedriver를 사용해 크롬 페이지를 연다.

- implicitly_wait(3): 브라우저를 오픈할 때 약간의 시간간격을 줘야 이미지가 크롤링된다. 실제로 해당 부분 코드를 지우면 브라우저가 열리자마자 닫힌다.

- get(url): chrome에서 해당 url로 접속한다.

 

 

3. 이미지 긁어오기

images = browser.find_elements_by_class_name("_image")

 

 

네이버 이미지 검색 페이지 HTML을 분석해보면 각 이미지들이 '_image' 클래스를 갖고 있다. 이를 전부 긁어온다.

 

 

4. 저장 경로 설정

save_path = "/Users/danuri/Desktop/images/" + search_term + "/"
create_folder_if_not_exists(save_path)

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

 각자 원하는 저장 경로를 설정한다. 나는 '바탕화면/images/김치찌개' 로 검색어마다 'images/[검색어]' 디렉토리에 저장되도록 설정했다.

create_folder_if_not_exists는 해당 저장경로가 존재하지 않으면 생성해주는 함수다.

 

 

5. 이미지 저장

save_images(images, save_path)

def save_images(images, save_path):
    for index, image in enumerate(images[:10]):  # images[:크롤링하고 싶은 사진 개수]
        src = image.get_attribute('src')
        t = urlopen(src).read()
        file = open(os.path.join(save_path, str(index + 1) + ".jpg"), "wb")
        file.write(t)
        print("img save " + save_path + str(index + 1) + ".jpg")

설정한 저장 경로(save_path)에 긁어온 이미지들(images)을 저장한다. 

나는 검색어당 10장이면 충분해서 10장만 저장하도록 했다. (1.jpg ~ 10.jpg)

 

 

6. 마무리

print(search_term + " 저장 성공")
browser.close()

마지막으로 chrome 브라우저를 닫아준다.

 

 

<실행 결과>

원하는 검색어: 김치찌개
img save /Users/danuri/Desktop/images/김치찌개/1.jpg
img save /Users/danuri/Desktop/images/김치찌개/2.jpg
img save /Users/danuri/Desktop/images/김치찌개/3.jpg
img save /Users/danuri/Desktop/images/김치찌개/4.jpg
img save /Users/danuri/Desktop/images/김치찌개/5.jpg
img save /Users/danuri/Desktop/images/김치찌개/6.jpg
img save /Users/danuri/Desktop/images/김치찌개/7.jpg
img save /Users/danuri/Desktop/images/김치찌개/8.jpg
img save /Users/danuri/Desktop/images/김치찌개/9.jpg
img save /Users/danuri/Desktop/images/김치찌개/10.jpg
김치찌개 저장 성공

 

 

 

크롤링 성공!