들어가며
크롤링 및 시각화의 마지막 수업으로 구글 이미지의 크롤링이 남아있다. 이미지 크롤링이 끝난 후에는 이 때까지 배운 것을 활용하여 미니프로젝트를 진행하게 될텐데 일단 이미지 크롤링 실습부터 진행해보자.
구글 이미지 크롤링
1. 라이브러리 불러오기
spyder를 열고 필요한 라이브러리부터 불러오자. 구글 검색창에 검색하고자 하는 것을 입력하기 위한 이벤트를 줄 것이기 때문에 `Keys`를 추가했고, 파일생성을 위해서 운영체제 시스템에 접근할 수 있는 `os`도 추가했다.
from selenium import webdriver # 웹애플리케이션 테스트 자동화 도구
# Selenium을 사용하여 크롬브라우저를 자동화할 때 필요한 크롬 드라이버를 관리하는 데 사용
from webdriver_manager.chrome import ChromeDriverManager
# 크롬브라우저 서비스를 제어하기 위해 필요한 클래스
from selenium.webdriver.chrome.service import Service as ChromeService
# Selenium WebDriver를 사용하여 웹 브라우저를 자동화할 때 키보드의 키 입력을 시뮬레이션
from selenium.webdriver.common.keys import Keys
# 웹 페이지에서 특정 요소를 식별하기 위한 메서드 제공
from selenium.webdriver.common.by import By
import urllib.request # 웹 리소스 접근
import time # 시간 지연 목적
import os # 폴더 생성 목적
2. 폴더 생성 함수 선언
이미지 파일을 저장하기 위해 새로운 폴더를 만들어주는 함수를 작성한다.
def createFolder(directory):
try:
if not os.path.exists(directory): # 이 경로에 폴더가 존재하면
os.makedirs(directory)
except:
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())
# WebDriver 객체 생성 및 Chrome 브라우저 실행
driver = webdriver.Chrome(service=service, options=options)
4. 키워드 검색
이미지 검색창 안에 설정한 키워드를 삽입하기 위해서 `textarea` 태그 안에 `name=q` 속성을 이용한다. 그 이유는 검색한 페이지에서 주소창을 확인해보면 `q=꽃` 즉, 검색 키워드가 q라는 변수에 할당되었기 때문이다. `find_element`메서드로 `q`를 찾아준 후, `send_keys`를 이용해서 설정한 키워드를 검색창에 입력해준다. 그리고 `Keys.RETURN`으로 엔터키 이벤트를 발생시킨다.
print('2. 키워드 검색: ', keyword)
driver.get('https://www.google.co.kr/imghp?hl=ko') # 페이지 접속
# 검색창에 키워드 입력 -> 입력 태그의 name 속성을 이용해서 요소 찾기
# 구글 이미지 검색 textarea name="q"
input_keyword = driver.find_element(By.NAME, 'q')
input_keyword.send_keys(keyword) # keyword단어 검색창에 입력
# 검색(엔터) 키 전송
input_keyword.send_keys(Keys.RETURN)
5. 스크롤 내리기
검색한 결과의 모든 이미지를 수집하기 위해 맨 밑까지 스크롤을 내려줌으로써 이미지 렌더링을 모두 완료시킨다.
SCROLL_PAUSE_TIME = 5 # 변하지 않는 상수, 유지보수를 위함
# 현재 상황에서 스크롤이 가능한 범위까지의 높이를 저장
last_height = driver.execute_script('return document.body.scrollHeight')
while True:
print('스크롤 중...', keyword)
# 스크롤을 최대로 내리기
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. 이미지 검색 개수 확인
이미지 틀을 모두 찾아서 `div`에 저장하고, `div`안에 `img`태그 class가 `YQ4gaf`인 것을 모두 찾아서 `images`리스트에 추가해준다. 유튜브 썸네일 처럼 이미지 링크가 없는 이미지가 존재할 수 있기 때문에 `src`값이 있는 것만 추출해서 `links`에 다시 저장해준다. 이 `links`의 길이가 바로 찾은 이미지의 개수이다.
images, links = [], []
# 이미지 틀 <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)
7. 이미지 다운로드 시작
`urlretrieve`를 이용하여 각 이미지마다 `src`에 있던 주소로 가서 이미지를 다운로드 받는다. 다운로드 받은 이미지는 두번째 매개변수로 지정한 경로에 넘버링되어 저장된다. 다운로드 실패시에는 `except`문에 있는 코드가 실행된다.
정상적으로 실행됐을 경우, 아래와 같이 해당 경로에 잘 저장된 것을 확인할 수 있다.
print('5. 이미지 다운로드 시작')
for i, v in enumerate(links):
try:
url = v
start = time.time() # 다운로드 시작시간 기록
# 실제 경로로 가서 파일이름 지정 후 다운로드, 꽃 넘버링
urllib.request.urlretrieve(url, './'+keyword+'_img_download/'+keyword+'_'+str(i+1)+'.jpg')
print(i+1, '/', len(links), keyword, '다운로드..Download time:', str(time.time()-start)[:5]+'초')
except:
# "1/980 꽃 다운로드 실패.."
print(i+1, '/', len(links), keyword, '다운로드 실패..')
pass
데이터 수집 및 시각화 팀 프로젝트 - 주제 선정
당장 다음날 오후 3시에 발표가 진행되기 때문에 속전속결로 진행해야했다. 팀원들과 자유롭게 1~2개씩 의견을 나누다가 모두 옷을 좋아한다는 공통점을 찾았고, 대한민국 대표적인 온라인 편집샵인 무신사를 크롤링 페이지로 선정했다. 그리고 ABC부트캠프가 ESG지원으로 운영되는 만큼, ESG와 연관지을 수 있는 요소를 탐색하다가 무신사에서 '무신사어스'라는 이름으로 환경을 고려한 상품들을 판매하고 있는 것을 알게 되었다. 따라서 이 무신사어스의 상품후기 분석을 통해 소비자들이 환경을 고려한 상품에 대해서 현재 어떤 반응을 보이고 있는지, 그리고 분석한 결과를 바탕으로 환경과 관련된 상품들이 어떤 방향성을 가지면 좋을지, 이 부분들을 중점적으로 다뤄서 진행하기로 의견을 모았다.
마무리
파이썬 기초 프로그래밍이 끝난지 얼마 안된 것 같은데 벌써 데이터 분석의 마지막 수업이 끝났다. 다소 짧은 시간이지만 그 과정 속에서 데이터 크롤링과 시각화 역량을 생각보다 많이 쌓았다고 느꼈다. 교수님 말씀처럼 에러를 겁내지 말고 계속 시도해보면서 많은 시행착오를 겪다보면 점점 더 성장할 수 있지 않을까 싶다.
'ABC부트캠프 테크노트' 카테고리의 다른 글
[17일차] ABC부트캠프 : 건양대 메디컬 캠퍼스 견학 (0) | 2024.07.26 |
---|---|
[16일차] ABC부트캠프 : 데이터 분석 팀 프로젝트(2/2) (0) | 2024.07.25 |
[14일차] ABC부트캠프 : 음악 정보 수집 및 시각화 (0) | 2024.07.23 |
[13일차] ABC부트캠프 : 유튜브 댓글 수집 및 시각화 (6) | 2024.07.22 |
[12일차] ABC부트캠프 : ESG포럼 & 세미나2 (0) | 2024.07.19 |