본문 바로가기

필기정리

[Web crawling] 구글에서 자동으로 원하는 이미지 다운받기

320x100
이미지 크롤링(image crawling)

 

이번 시간에는 딥러닝에 쓸 데이터셋을 구하던 중, 웹 크롤링의 방법이 생각보다 다양하여

한번 정리하고자 합니다. 웹 크롤링 기법이 사용된 이후로, selenium, beautifulsoup4 등 다양한 라이브러리들이

개발되고 있는데요. 이번 차시에서는 다른 것은 생략하고 깔끔하게 이미지만을 다뤄보겠습니다.

- google 이미지 사이트에서의 동적인 이미지 크롤링을 진행합니다.

 

selenium은 동적 크롤링을 지원합니다.

 

 

 

 

쉽게 말해, 이리저리 브라우저를 움직이면서 더 많은 데이터를 수집할 수 있는 것이 동적

움직임이 적거나 없는 것이 정적 크롤링 입니다! (*동적도 입력값이 작으면 더 적은 데이터를 가져올 수 있습니다)

 


전체 소스코드는 가장 아래에 공개하겠습니다. 설치를 건너 뛰어버리면 아예 동작이 안되기도 하고,

어디서 에러가 생겼는지 검사하기도 어려워지기 때문입니다

 

 

사용할 패키지는 selenium과 urllib, 그리고 html에 대한 간단한 지식입니다.

 

Selenium

 

Selenium

Selenium automates browsers. That's it!

www.selenium.dev

 

 

먼저, 사용 IDE는 jupyter를 사용했습니다.

 

중간에 webdriver_manager.chrome을 로드하지 못하고 오류가 생길때가 있습니다.

웹드라이버 매니저를 미리 설치해줍시다

 

!pip install webdriver-manager selenium

 

위에서 언급한것처럼 다양한 패키지들을 로드해줍니다.

 

from selenium.webdriver.common.keys import Keys
import time
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import urllib.request

 

인스톨이 잘 안되었다면, kernel을 통해 Restart를 하는 것도 좋은 방법입니다.

 

크롬의 옵션을 webdriver를 통해서 선언하고, 크롬 드라이버 매니저를 설치해줍니다.

# 크롬 옵션 설정
chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service = Service(ChromeDriverManager().install()), options=chrome_options)

 

 

 

사전 준비는 이제 끝났습니다.

 

들어갈 사이트를 준비해봅니다. 구글이 아닌 "구글 이미지검색" 사이트입니다.

 

# 들어갈 사이트 url(구글 이미지검색)
URL = "https://www.google.co.kr/imghp"
driver.get(url=URL)

 

로딩 시간을 대비해서 10초간 대비합니다. (인터넷 속도에 따라 더 빨라질 수 있는 implicitly_wait 사용)

 

# 10초간 대기
driver.implicitly_wait(time_to_wait=10)

 

인터넷 접속 후 화면에서 [F12]를 사용하거나 [SHIFT] + [CTRL] + [C] 하여 HTML에서 요소를 클릭하면

여러가지 요소들을 볼 수 있습니다. 

이번의 경우에는 구글 이미지검색에서 검색창을 들어가려 하는데요.

 

XPATH를 복사하여 붙여넣기 하면 아래 코드가 반환되게 됩니다.

 

# 웹상에서 "검색 창"에 포인트를 두고 들어갈 것임
keyElement = driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input")

 

그리고 KEYS 값으로 원하는 검색어를 입력해줍니다. 이번에는 맛있는 치킨을 입력했습니다.

 

# 검색 창에 'chicken'이라는 글자를 입력
keyElement.send_keys('chicken')

 

이 글자를 key로 받아서 return하도록 했습니다.

 

# 위 글자를 key로 받아서 리턴함
keyElement.send_keys(Keys.RETURN)

 

스크롤이 내려가는 동적인 기능을 구현하기 위해, TAG_NAME - body를 잡아줍니다.

그리고나서 12초동안 웹이 움직일때까지 기다려줍니다 (시간은 자유)

 

# 스크롤을 내려가는 것을 구현 (한번 내리고 12초동안 대기)
bodyElement = driver.find_element(By.TAG_NAME, "body")
time.sleep(12)

 

여기서 주의할 점은 과거 문서들을 보면 driver.find_element가 아닌 아래 코드를 사용하는 경우가 있습니다.

find_element_by_tag_name

 

하지만 이는 selenium 4로 업그레이드를 완료하면서, 바뀌게 되었답니다.

 

Upgrade to Selenium 4 | Selenium

 

Upgrade to Selenium 4

Are you still using Selenium 3? This guide will help you upgrade to the latest release!

www.selenium.dev

 

다만, 업그레이드가 벌써 2021년 10월에 일어난 일이니, 괜한 기우일수도 있겠네요.

위 문서를 참고해도 좋을 듯 합니다.

 

그리고 bodyElement로 보낸 키를 PAGE_DOWN을 통해서 아래로 내려가게 해줍니다.

12번 반복했고, 중간 중간에 0.2초동안 기다려서 너무 빨리 지나가지 않도록 구현했습니다.

 

# 12번의 반복 횟수동안 0.2초마다 bodyelement에 보낸 키가 down됨
for i in range(12):
    bodyElement.send_keys(Keys.PAGE_DOWN)
    time.sleep(0.2)

 

여기선는 css 셀렉터가 나옵니다.

아래 방법을 통해서 selector를 복사하면 값이 나오는데요.

 

#islrg > div.islrc > div:nth-child(9) > a.wXeWr.islib.nfEiy > div.bRMDJf.islir > img

 

여기서 div:nth-child(9)는 이미지의 순번(각각의 이미지)들을 나타냅니다. 다른 이미지에서도 공통적으로 반복됩니다.

이 텍스트에서 nth-child(9) 부분을 지워줍니다. 그리고 images로 넣어줄 것입니다.

 

# CSS 셀렉터를 통해 이미지 목록의 이미지들을 images 변수에 저장
images = driver.find_elements(By.CSS_SELECTOR, '#islrg > div.islrc > div > a.wXeWr.islib.nfEiy > div.bRMDJf.islir > img')

 

for문을 통해서 이미지의 번호를 저장하고, imageurl 리스트에 따로 넣어줍니다.

이는 url 링크를 활용해서 .jpg를 붙이고, jpg파일로 변환하는데 쓰일 것입니다.

 

# 이미지의 번호를 저장할 것
imageURL = []
for image in images: # src 어트리뷰트를 활용
    if image.get_attribute('src') is not None: # src가 비어있지 않으면
        imageURL.append(image.get_attribute('src')) # 이미지 url을 리스트에 붙여줄 것임

 

urllib를 통해 다운로드 해옵니다.

여기서 urllib.request.urlretrieve는 (url, filename)을 인수로 받아서 url자체를 지정한 형식으로 다운로드할 수 있게 해줍니다.

 

 

필자의 PC 이름이 들어가서 이름은 가렸습니다. 

이 코드를 통해 내 PC의 바탕화면으로 저장할 수 있게 됩니다! (JPG 형식)

형식 자체는 png도 가능합니다.

 

# urllib은 정적 크롤링 방식으로, 이번에는 이미지 url을 다운로드  
for i, j in enumerate(imageURL):
    urllib.request.urlretrieve(j, 'C:/Users/PC이름/Desktop/chicken/' + str(i) + '.jpg')

 

그러면 이렇게, 12번 스크롤 내린 범위의 이미지들이 미리 지정한 폴더에 저장되게 됩니다!

스크롤 횟수를 20, 30, 100등으로 바꾸면 더 많은 이미지들이 들어올 것입니다.

 

 

전체 코드

마지막으로 소스코드를 보면서 크롤링을 마치겠습니다.

 

from selenium.webdriver.common.keys import Keys
import time
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import urllib.request

# 크롬 옵션 설정
chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service = Service(ChromeDriverManager().install()), options=chrome_options)

# 들어갈 사이트 url(구글 이미지검색)
URL = "https://www.google.co.kr/imghp"
driver.get(url=URL)

# 10초간 대기
driver.implicitly_wait(time_to_wait=10)

# 웹상에서 "검색 창"에 포인트를 두고 들어갈 것임
keyElement = driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input")

# 검색 창에 'chicken'이라는 글자를 입력
keyElement.send_keys('chicken')

# 위 글자를 key로 받아서 리턴함
keyElement.send_keys(Keys.RETURN)


# 스크롤을 내려가는 것을 구현 (한번 내리고 12초동안 대기)
bodyElement = driver.find_element(By.TAG_NAME, "body")
time.sleep(12)

# 첫번째 페이지가 아닌 다른 페이지도 내려가는 방법

# 12번의 반복 횟수동안 0.2초마다 bodyelement에 보낸 키가 down됨
for i in range(12):
    bodyElement.send_keys(Keys.PAGE_DOWN)
    time.sleep(0.2)
    
# CSS 셀렉터를 통해 이미지 목록의 이미지들을 images 변수에 저장
images = driver.find_elements(By.CSS_SELECTOR, '#islrg > div.islrc > div > a.wXeWr.islib.nfEiy > div.bRMDJf.islir > img')

# 이미지의 번호를 저장할 것
imageURL = []
for image in images: # src 어트리뷰트를 활용
    if image.get_attribute('src') is not None: # src가 비어있지 않으면
        imageURL.append(image.get_attribute('src')) # 이미지 url을 리스트에 붙여줄 것임

# urllib은 정적 크롤링 방식으로, 이번에는 이미지 url을 다운로드  
for i, j in enumerate(imageURL):
    urllib.request.urlretrieve(j, 'C:/Users/임채원/Desktop/chicken/' + str(i) + '.png')
728x90