이미지 프로세서에서 이미지를 다운로드하는 메서드를 Playwright에서 Requests로 변경하고, 재시도 로직 및 HTTP 헤더 설정을 추가하여 안정성을 향상시켰습니다. 관련 로그도 개선하였습니다.

This commit is contained in:
Envy_PC 2025-07-18 21:32:15 +09:00
parent fb6c31e230
commit f969bb84e3
1 changed files with 58 additions and 20 deletions

View File

@ -392,8 +392,12 @@ class ImageProcessor3:
return local_image_path
async def download_image(self, page, image_url, index, file_prefix=""):
"""Playwright를 사용해 이미지를 다운로드합니다"""
def download_image(self, image_url, index, file_prefix="", max_retries=3):
"""Requests를 사용해 이미지를 다운로드합니다"""
import requests
import time
import random
# 로컬 파일 경로면 바로 반환
if os.path.isfile(image_url):
self.logger.log(f"로컬 파일 경로 감지, 다운로드 생략: {image_url}", level=logging.DEBUG)
@ -420,24 +424,57 @@ class ImageProcessor3:
local_path = os.path.join(self.TEMP_IMAGE_DIR, filename)
# Playwright로 이미지 다운로드
response = await page.request.get(image_url)
if response.status == 200:
image_data = await response.body()
# 이미지 데이터 유효성 검사
if self.is_valid_image_data(image_data):
async with aiofiles.open(local_path, 'wb') as f:
await f.write(image_data)
# HTTP 헤더 설정
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"DNT": "1", # Do Not Track 요청 헤더
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Cache-Control": "max-age=0"
}
retries = 0
while retries < max_retries:
try:
self.logger.log(f"이미지 다운로드 중: {filename}", level=logging.DEBUG)
response = requests.get(image_url, headers=headers, stream=True, timeout=30)
self.logger.log(f"이미지 다운로드 완료: {filename}", level=logging.DEBUG)
return local_path
else:
self.logger.log(f"유효하지 않은 이미지 데이터: {image_url}", level=logging.WARNING)
return None
else:
self.logger.log(f"이미지 다운로드 실패 (HTTP {response.status}): {image_url}", level=logging.ERROR, exc_info=True)
return None
if response.status_code == 200:
image_data = response.content
# 이미지 데이터 유효성 검사
if self.is_valid_image_data(image_data):
with open(local_path, 'wb') as f:
f.write(image_data)
self.logger.log(f"이미지 다운로드 완료: {filename}", level=logging.DEBUG)
return local_path
else:
self.logger.log(f"유효하지 않은 이미지 데이터: {image_url}", level=logging.WARNING)
return None
else:
self.logger.log(f"이미지 다운로드 실패 (HTTP {response.status_code}): {image_url}. 재시도 {retries + 1}/{max_retries}", level=logging.ERROR)
retries += 1
if retries < max_retries:
time.sleep(random.randint(2, 5)) # 2~5초 대기 후 재시도
except requests.exceptions.RequestException as e:
self.logger.log(f"이미지 다운로드 중 네트워크 오류: {e}. 재시도 {retries + 1}/{max_retries}", level=logging.ERROR)
retries += 1
if retries < max_retries:
time.sleep(random.randint(2, 5)) # 예외 발생 시 대기 후 재시도
except Exception as e:
self.logger.log(f"이미지 다운로드 중 예상치 못한 오류: {e}. 재시도 {retries + 1}/{max_retries}", level=logging.ERROR)
retries += 1
if retries < max_retries:
time.sleep(random.randint(2, 5))
self.logger.log(f"이미지 다운로드 최대 재시도 횟수를 초과했습니다: {image_url}", level=logging.ERROR)
return None
except Exception as e:
self.logger.log(f"이미지 다운로드 중 오류: {e}", level=logging.ERROR, exc_info=True)
@ -899,7 +936,8 @@ class ImageProcessor3:
# 1. 다운로드 또는 로컬 경로 확정
if original_image_url.startswith("http"):
# 다운로드 재사용을 위해 기존 메서드 호출
local_path = await self.download_image(page=page, image_url=original_image_url, index=0, file_prefix=file_prefix)
# local_path = await self.download_image(page=page, image_url=original_image_url, index=0, file_prefix=file_prefix)
local_path = await self.download_image(image_url=original_image_url, index=0, file_prefix=file_prefix)
if not local_path:
return {"status": "failed", "path": original_image_url, "error": "다운로드 실패"}
else: