실내 운동 기구 object detection 을 해보고 싶어 이번에 구글에서 이미지 크롤링으로 이미지 데이터를 수집해 보았다.
selenium 크롤링은 간단히 말해 우리가 일일히 손으로 타자 쳐서 검색하고, 이미지를 클릭하고, 이미지를 저장하는 일련의 과정을 자동적으로 해주는 메소드이다. automatically control!! 신기했다. 가상환경에서 실행된다.
아래 코드는 selenium 관련 명령어+python이 주로 이루어져 있으며,
time과 관련된 명령어들은 '클릭할 때', '페이지를 로딩할 때', '스크롤할 때' 조금 기다리게 하여 과도하게 빠르게 진행되는 현상을 막는다.
import threading
from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--incognito")
chrome_options.add_argument("--headless")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-setuid-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_experimental_option('excludeSwitches',['enable-logging'])
#browser = webdriver.Chrome('chromedriver', chrome_options=chrome_options)
from selenium.webdriver.common.keys import Keys
import time
import urllib.request
from selenium.webdriver.common.by import By
search = "latpull+down+png" #내가 구글에 검색하고자 하는 키워드
driver = webdriver.Chrome('./chromedriver.exe') #이미지를 많이 받기 위해서 필요하다.
driver.get("https://www.google.co.kr/imghp?hl=ko&tab=wi&authuser=0&ogbl")
elem = driver.find_element(By.NAME, "q")
elem.send_keys(search)
elem.send_keys(Keys.RETURN)
SCROLL_PAUSE_TIME = 3
# Get scroll height
last_height = driver.execute_script("return document.body.scrollHeight")
SAVE_FLAG = False
def timeout(limit_time): #timeout
start = time.time()
while True:
if time.time() - start > limit_time or SAVE_FLAG:
raise Exception('timeout. or image saved.')
while True: #검색 결과들을 스크롤해서 미리 로딩해둔다. 검색어 이미지의 가장 아래까지 내려감
# Scroll down to bottom
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Wait to load page
time.sleep(SCROLL_PAUSE_TIME)
# Calculate new scroll height and compare with last scroll height
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
try:
driver.find_elements(By.CSS_SELECTOR,".mye4qd").click()
except:
break
last_height = new_height
images = driver.find_elements(By.CSS_SELECTOR,".rg_i.Q4LuWd")
count = 0
for image in images:
SAVE_FLAG = False
timer = threading.Thread(target=timeout, args=(50,))
try:
image.click()
time.sleep(2)
timer.start()
#이미지의 XPath 를 붙여넣기 해준다. F12를 통해 페이지 소스의 XPath를 복사한다.
imgUrl = driver.find_element(By.XPATH,'/html/body/div[2]/c-wiz/div[3]/div[2]/div[3]/div/div/div[3]/div[2]/c-wiz/div/div[1]/div[1]/div[3]/div/a/img').get_attribute("src")
urllib.request.urlretrieve(imgUrl, search + "_{0:04}".format(count) + ".jpg") #저장할 이미지의 경로 지정
print('Save images : ', search + "_{0:04}".format(count) + ".jpg")
SAVE_FLAG = True
count += 1
if timer.is_alive():
timer.join()
except Exception as e:
if timer.is_alive():
timer.join()
pass
print('driver end. Total images : ', count)
driver.close()
아래와 같이 파일에 차곡차곡 이미지가 쌓인다 !!👍
트러블 슈팅
- selenium이 버전이 3->4로 업그레이드되면서 명령어가 바뀌어서 헷갈렸다. (최근에 바뀐 것으로 보임. elements와 element의 명령어를 주의하자..!!)
#버전 3
driver.find_element_by_name("q")
#버전 4
driver.find_element(By.NAME, "q")
- visual studio code에서 가상환경에서 다운받은 것들(ex.selenium, google_images_download)을 사용할 때에는 환경을 python에서 가상환경으로 바꿔준 후 실행하면 좋다. 아래 사진처럼 python 3.9.7 ('base')로
- 이미지를 저장할 경로를 설정할 때 만약 "img/"+ ~~ 이렇게 썼다면 이 img에 해당하는 폴더는 이미 존재하고 있어야 한다.
- F12를 이용해서 크롬에서 이미지의 XPath를 가져오는 과정이 있는데, 이 path는 만약 웹사이트가 보완된다거나 하면 이후에 바뀔 수도 있으니 확인이 필요하다.