파이썬으로 특정 사이트의 모든 이미지 다운로드 받기
Language/Python2024. 9. 4. 22:14본 글에서는 파이썬으로 특정 사이트의 이미지를 모두 다운로드 받는 코드에 대해 설명합니다.
의존성 설치
selenium 설치
requests로 웹 파일을 가져올 수도 있지만, React와 같이 javascript에 의해 만들어지는 사이트의 경우는 아무것도 없는 html 파일을 가지고 올 수 있습니다. 따라서, 실제 브라우저 엔진을 사용하여 웹 파일을 읽어올 수 있도록 해주는 selenium
을 설치해야 합니다.
pip install selenium
webdriver-manager 설치
그리고, 웹 브라우저 엔진을 다운로드 받아야 합니다.
위 사이트에서 다운로드 받을 수 있긴 하지만 본 글에서는 브라우저 엔진도 자동으로 설치해주는 webdriver-manager
의존성을 추가하여 사용할 예정입니다.
pip install webdriver-manager
이를 통해 별도로 브라우저 엔진을 다운로드 필요 없이, Selenium 스크립트를 실행할 때마다 최신 드라이버를 자동으로 다운로드하고 사용할 수 있습니다.
Python 코드 작성
우선 수집할 사이트의 주소와 이미지를 저장할 결과물 위치를 정하는 코드를 작성합니다.
# -*- coding: utf-8 -*-
import os
# 이미지를 수집할 주소
base_url = 'https://www.google.com'
sub_url = '/search?sca_esv=c7a01837b1eb8e0f&sxsrf=ADLYWIK8P6p3w3H_k5K7bVkRGfHjMS-Oaw:1725453920690&q=pepe&udm=2&fbs=AEQNm0DmKhoYsBCHazhZSCWuALW8l8eUs1i3TeMYPF4tXSfZ98Z_XVxzNb13fp2atSe3aTZxh00P4RN46vKaeCU6lCwgokKSAjPDH2MlsSy-8gaDDT-JNivITOer-gOj0vQqolKg3Q9YPkP_Nw_v6C_YOb5Nw0iVQYCsQ8hA8-cqMCop9-Mqj8y3GnB-Ikay4uMy0YyKWT552uXarkOzVsrI9QNBxTuH1A&sa=X&ved=2ahUKEwigmpPgqKmIAxU0hlYBHY98MRIQtKgLegQIDhAB&biw=2560&bih=1294&dpr=2'
target_url = base_url + sub_url
# 이미지를 저장할 디렉토리 이름
save_dir_name = 'download'
curpath = os.path.dirname(__file__)
save_dir_path = os.path.join(curpath, save_dir_name)
print("저장된 이미지 디렉토리 경로:", save_dir_path)
# 디렉토리가 없으면 생성
if not os.path.exists(save_dir_path):
os.makedirs(save_dir_path)
이후 웹 드라이버를 다운로드하고 초기화하는 코드를 작성합니다.
아래 코드를 보면 time.sleep
으로 5초 정도 기다리는 코드가 있는데, 브라우저가 완전히 열리고 렌더링이 다 될때까지 기다리기 위해 추가했습니다. 그리고, 만일의 예상하지 못한 에러가 발생한 경우, 리소스 해제를 위해 try-finally
로 리소스를 해제하는 코드를 작성했습니다.
# ChromeDriver 다운로드
chrome_driver = ChromeDriverManager().install()
# WebDriver 초기화
service = Service(chrome_driver)
driver = webdriver.Chrome(service=service)
try:
# 웹 페이지 로드
driver.get(target_url)
time.sleep(5) # 페이지가 완전히 로드될 때까지 대기
finally:
driver.quit()
위 코드를 실행하면, 아래와 같이 chrome 브라우저가 열리게 됩니다. 저는 구글에서 pepe를 검색한 사이트를 target_url로 설정했습니다.
이제 이미지를 태그를 모두 가져와서 로컬에 이미지를 저장하는 코드를 작성해봅시다. img 태그를 모두 가져온 뒤에 src에서 이미지의 주소를 가지고 옵니다. 그리고 requests로 해당 이미지를 가지고 온다음 바이너리 쓰기로 파일을 저장합니다.
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import requests
import os
import time
import base64
import random
import string
# 이미지를 수집할 주소
base_url = 'https://www.google.com'
sub_url = '/search?sca_esv=c7a01837b1eb8e0f&sxsrf=ADLYWIK8P6p3w3H_k5K7bVkRGfHjMS-Oaw:1725453920690&q=pepe&udm=2&fbs=AEQNm0DmKhoYsBCHazhZSCWuALW8l8eUs1i3TeMYPF4tXSfZ98Z_XVxzNb13fp2atSe3aTZxh00P4RN46vKaeCU6lCwgokKSAjPDH2MlsSy-8gaDDT-JNivITOer-gOj0vQqolKg3Q9YPkP_Nw_v6C_YOb5Nw0iVQYCsQ8hA8-cqMCop9-Mqj8y3GnB-Ikay4uMy0YyKWT552uXarkOzVsrI9QNBxTuH1A&sa=X&ved=2ahUKEwigmpPgqKmIAxU0hlYBHY98MRIQtKgLegQIDhAB&biw=2560&bih=1294&dpr=2'
target_url = base_url + sub_url
# 이미지를 저장할 디렉토리 이름
save_dir_name = 'download'
curpath = os.path.dirname(__file__)
save_dir_path = os.path.join(curpath, save_dir_name)
print("저장된 이미지 디렉토리 경로:", save_dir_path)
# 디렉토리가 없으면 생성
if not os.path.exists(save_dir_path):
os.makedirs(save_dir_path)
# ChromeDriver 다운로드
chrome_driver = ChromeDriverManager().install()
# WebDriver 초기화
service = Service(chrome_driver)
driver = webdriver.Chrome(service=service)
try:
# 웹 페이지 로드
driver.get(target_url)
time.sleep(5) # 페이지가 완전히 로드될 때까지 대기
# 모든 이미지 태그 찾기
images = driver.find_elements(By.TAG_NAME, 'img')
# 이미지 다운로드
for img in images:
img_url = img.get_attribute('src')
if not img_url:
continue
try:
# data: 로 시작하는 경우, data URL 이므로 base64로 디코딩 이후 다운로드
if img_url.startswith("data:"):
# 데이터가 "data:image/png;base64,"으로 시작하므로, 해당 내용을 제거하여 Base64 데이터만 추출
header, encoded = img_url.split(",", 1)
# Base64 디코딩
image_data = base64.b64decode(encoded)
# 이미지 파일 저장
extension = header.split('/')[1].split(';')[0]
random_name = ''.join(random.choices(string.ascii_letters + string.digits, k=8))
filename = random_name + "." + extension
with open(os.path.join(save_dir_path, filename), 'wb') as f:
f.write(image_data)
continue
# 상대 경로인 경우 절대 URL로 변환
if not img_url.startswith(('http://', 'https://')):
img_url = '/'.join([base_url, img_url])
# 이미지 데이터 가져오기
print("img_url", img_url)
img_response = requests.get(img_url)
img_response.raise_for_status() # HTTP 에러가 있는 경우 예외 발생
# 파일 이름 추출
img_name = os.path.basename(img_url.split('?')[0]) # 쿼리 스트링 제거
img_path = os.path.join(save_dir_path, img_name)
# 이미지 파일 저장
with open(img_path, 'wb') as f:
f.write(img_response.content)
print(f"Downloaded {img_url} to {img_path}")
except Exception as e:
print(f"Failed to download {img_url}: {e}")
finally:
driver.quit()
결과
수집을 못하는 이미지도 있긴 하지만 아래와 같이 이미지를 다운로드 받을 수 있습니다. 목표로 설정한 사이트의 특징에 맞게 코드를 보완하면 더욱 완벽하게 이미지를 다운로드 받을 수 있습니다.
'Language > Python' 카테고리의 다른 글
Python에서 gTTS 라이브러리로 TTS 음성 파일 생성하기 (2) | 2024.09.05 |
---|---|
PyInstaller로 파이썬 코드를 exe 파일로 빌드하기 (0) | 2024.08.23 |
파이썬의 모듈(module)과 패키지(package) (0) | 2024.08.23 |
Python에서 예외 발생시키는 방법 (raise Exception) (0) | 2024.08.22 |
Python에서 예외 처리하는 방법 (try ~ except) (0) | 2024.08.22 |
IT 기술에 대한 글을 주로 작성하고, 일상 내용, 맛집/숙박/제품 리뷰 등 여러가지 주제를작성하는 블로그입니다. 티스토리 커스텀 스킨도 개발하고 있으니 관심있으신분은 Berry Skin을 검색바랍니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!