오늘의 크롤링 주제는 이미지 수집이다.

수집하기 위한 사이트는 아래와 같다.

 

https://www.google.co.kr/imghp?hl=ko

 

Google 이미지

 

www.google.co.kr

 

구글 이미지에서 키워드를 입력하면 키워드에 맞는 사진들을 볼 수 있다.

 

우리는 오늘 검색한 사진들을 다운로드 받기 위한 코드를 작성해볼 것이다.

 

 


 

 

라이브러리 호출

 

마찬가지로 수집하기 위한 라이브러리를 호출한다.

 

# 1. 필요 모듈 임포트
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import urllib.request

import time
import os

 

수집은 BeautifulSoup가 아닌 제목과 같이 셀레니움을 사용한다.

 

위와 같이 수집에 필요한 라이브러리들이므로 반드시 호출해주자.

 

 

 

폴더 생성

 

다운로드한 이미지를 저장할 폴더를 생성해야 한다.

 

폴더를 생성하기 위한 코드는 아래와 같다.

# 파일 생성
os.path.exists('./' + '파일명'):
os.makedirs('./' + '파일명')

 

코드를 실행하면 코드가 담긴 경로상에 파일이 생성되게 된다.

 

 

 

웹 브라우저 자동화 설정

 

브라우저를 띄우기 위해 드라이버 설정을 거쳐야 한다.

# 드라이버 설정
options = webdriver.ChromeOptions()
options.add_argument('--no-sandbox') # 보안 기능인 샌드박스 비활성화
options.add_argument('--disable-dev-shm-usage') # dev/shm 디렉토리 사용 안함

service = ChromeService(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service = service, options = options)

 

위 설정은 12일차와 13주차에서도 동일한 과정을 수행했다.

 

브라우저를 띄우기 위한 코드이므로 해당 과정이 필요한 코드에는 반드시 필요하다.

 

 

 

키워드 검색

 

브라우저를 띄웠다면 크롤링 하기 전 구글 이미지로 접속하여 키워드를 입력하고 가장 아래로 페이지를 이동시켜야 한다.

 

# 4. 키워드 검색
print('2. 키워드 검색 : ', keyword)
driver.get('https://www.google.co.kr/imghp?hl=ko')

# 검색창 element 찾기 / 구글 이미지 검색은 textarea name="q"
input_keyword = driver.find_element(By.NAME, 'q')
input_keyword.send_keys(keyword)

# 입력 값 전송
input_keyword.send_keys(Keys.RETURN)

# 5.스크롤 내리기
SCROLL_PAUSE_TIME = 3

last_height = driver.execute_script('return document.body.scrollHeight')
print('3. 스크롤 중...' + keyword)
while True:
    driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
    time.sleep(SCROLL_PAUSE_TIME)
    
    new_height = driver.execute_script('return document.body.scrollHeight')
    
    if new_height == last_height:
        break
    
    last_height = new_height
    time.sleep(SCROLL_PAUSE_TIME)

 

드라이버에 URL을 전달하고 스크롤을 가장 아래로 내리면서 딜레이를 거쳐 가장 아래로 내려가게 된다.

 

이때도 사람같이 움직이기 위해 딜레이를 발생시켜야 한다.

 

 

 

이미지 검색 개수 확인 및 이미지 다운로드

 

우선은 이미지 태그를 감싼 div를 찾아야 한다.

 

그렇게 div 태그를 찾으면 리스트로 저장하여 다시 이미지를 찾는 과정을 수행해야 한다.

 

# 6. 이미지 검색 개수 확인 및 다운로드
links = []
images = []

# img 태그를 감싼 div 찾기 <div class="H8Rx8c">
div = driver.find_elements(By.CLASS_NAME, 'H8Rx8c')

for i in div:
    img_tag = i.find_element(By.CLASS_NAME, 'YQ4gaf')
    images.append(img_tag)
    
print('4. 이미지의 개수 확인...')
for image in images :
    if image.get_attribute('src') != None:
        links.append(image.get_attribute('src'))
        
print(keyword + '찾은 이미지 개수 : ', len(links))
time.sleep(SCROLL_PAUSE_TIME)

 

 

 

이미지 다운로드

 

이제 links에 들어간 요소들을 하나씩 순회하면서 이미지를 다운로드하는 과정이다.

 

이때도 예외가 발생하면 코드가 멈춰버리기 때문에 try - except문을 사용하여 예외가 발생하더라도 코드가 멈추지 않도록 예외 처리를 해줘야 한다.

 

for i, v in enumerate(links):
    try:
        url = v
        start = time.time()
        urllib.request.urlretrieve(url,
                                   './'+keyword+'_img download/' + keyword + '_' + str(i) + '.jpg')
        print(str(i+1) + '/' + str(len(links)) + ' ' + keyword + ' 다운로드... Download time: ' + str(time.time() - start)[:5] + ' 초')
    
    except:
        print(str(i+1) + '/' + str(len(links)) + ' ' + keyword + ' 다운로드 실패..')
        pass

 

 

 

 

구글 이미지 다운로드 실습 코드 전문

 

# 1. 필요 모듈 임포트
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import urllib.request

import time
import os

# 2. 폴더 생성 함수 선언
def createFolder(directory):
    try:
        if not os.path.exists(directory):
            os.makedirs(directory)
    
    except OSError:
        print("Error : Creating directory.." + directory)
        
# 3. 키워드 입력 및 폴더 생성
keyword = '꽃'
createFolder('./'+keyword+'_img download')
print('1. 키워드 설정 및 폴더 생성 완료...')

options = webdriver.ChromeOptions()
options.add_argument('--no-sandbox') # 보안 기능인 샌드박스 비활성화
options.add_argument('--disable-dev-shm-usage') # dev/shm 디렉토리 사용 안함

service = ChromeService(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service = service, options = options)

driver.implicitly_wait(3)

# 4. 키워드 검색
print('2. 키워드 검색 : ', keyword)
driver.get('https://www.google.co.kr/imghp?hl=ko')

# 검색창 element 찾기 / 구글 이미지 검색은 textarea name="q"
input_keyword = driver.find_element(By.NAME, 'q')
input_keyword.send_keys(keyword)

# 입력 값 전송
input_keyword.send_keys(Keys.RETURN)

# 5.스크롤 내리기
SCROLL_PAUSE_TIME = 3

last_height = driver.execute_script('return document.body.scrollHeight')
print('3. 스크롤 중...' + keyword)
while True:
    driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
    time.sleep(SCROLL_PAUSE_TIME)
    
    new_height = driver.execute_script('return document.body.scrollHeight')
    
    if new_height == last_height:
        break
    
    last_height = new_height
    time.sleep(SCROLL_PAUSE_TIME)
    
# 6. 이미지 검색 개수 확인 및 다운로드
links = []
images = []

# img 태그를 감싼 div 찾기 <div class="H8Rx8c">
div = driver.find_elements(By.CLASS_NAME, 'H8Rx8c')

for i in div:
    img_tag = i.find_element(By.CLASS_NAME, 'YQ4gaf')
    images.append(img_tag)
    
print('4. 이미지의 개수 확인...')
for image in images :
    if image.get_attribute('src') != None:
        links.append(image.get_attribute('src'))
        
print(keyword + '찾은 이미지 개수 : ', len(links))
time.sleep(SCROLL_PAUSE_TIME)
        
print('5. 이미지 다운로드 시작...')

for i, v in enumerate(links):
    try:
        url = v
        start = time.time()
        urllib.request.urlretrieve(url,
                                   './'+keyword+'_img download/' + keyword + '_' + str(i) + '.jpg')
        print(str(i+1) + '/' + str(len(links)) + ' ' + keyword + ' 다운로드... Download time: ' + str(time.time() - start)[:5] + ' 초')
    
    except:
        print(str(i+1) + '/' + str(len(links)) + ' ' + keyword + ' 다운로드 실패..')
        pass
print(keyword + '------다운로드 종료------')