feat: Add image download fallback via AutoDB AJAX API

When __carPhoto URL pattern returns 404 (e.g., timestamp-based filenames
like 1767161441_0.jpg instead of cmcar_0.jpg), fall back to fetching
actual image URLs from /common/ajax/AutoDB.html?mode=view&key={car_key}
XML response (strPhotos field).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
AutonetSellCar Deploy
2026-04-02 12:48:13 +09:00
parent 958ea252bb
commit f01abfa15e

View File

@@ -758,6 +758,64 @@ class CarmodooClient:
return result
async def get_car_image_urls(self, car_key: str) -> List[str]:
"""AutoDB AJAX API를 통해 차량 이미지 URL 목록을 가져옴
dealerCarView.html이 사용하는 /common/ajax/AutoDB.html?mode=view&key={car_key}
AJAX 엔드포인트를 호출하여 XML 응답의 strPhotos 필드에서 이미지 URL을 추출.
Args:
car_key: 암호화된 차량 키
Returns:
이미지 URL 리스트 (최대 20개)
"""
if not car_key:
return []
if not self.is_logged_in:
await self.login()
try:
async with httpx.AsyncClient(timeout=30.0, cookies=self.cookies) as client:
url = f"{CARMODOO_BASE_URL}/common/ajax/AutoDB.html"
params = {"mode": "view", "key": car_key}
response = await client.get(url, params=params, headers=self.headers)
if response.status_code == 200:
try:
xml_text = response.content.decode('euc-kr')
except:
xml_text = response.content.decode('utf-8', errors='replace')
# strPhotos 추출 (XML 태그, CDATA 포함 가능)
photos_match = re.search(r'<strPhotos>(.*?)</strPhotos>', xml_text, re.DOTALL)
if photos_match:
photos_str = photos_match.group(1).strip()
# CDATA 태그 제거
photos_str = re.sub(r'<!\[CDATA\[', '', photos_str)
photos_str = re.sub(r'\]\]>', '', photos_str)
photos_str = photos_str.strip()
if photos_str:
urls = [u.strip() for u in photos_str.split("##") if u.strip()]
# 상대 경로를 절대 경로로 변환
full_urls = []
for u in urls:
if u.startswith('http'):
full_urls.append(u)
elif u.startswith('/'):
full_urls.append(f"{CARMODOO_BASE_URL}{u}")
else:
full_urls.append(f"{CARMODOO_BASE_URL}/{u}")
print(f"[Image Fallback] Found {len(full_urls)} image URLs from AutoDB for key={car_key[:20]}...")
return full_urls
except Exception as e:
print(f"Get car image URLs error: {e}")
return []
async def get_performance_check(self, car_no: str, car_key: str = "", check_num: str = "") -> dict:
"""성능점검표 가져오기 - ck.carmodoo.com에서 조회
@@ -1520,6 +1578,25 @@ async def import_cars_from_carmodoo(
if i > 0:
break
# 폴백: __carPhoto에서 이미지를 못 가져온 경우 AutoDB AJAX로 실제 URL 조회
if len(downloaded_images) == 0 and car_data.car_key:
print(f"[Image Fallback] No images from __carPhoto for car {car.id} (car_no={car_data.car_no}), trying AutoDB...")
fallback_urls = await carmodoo_client.get_car_image_urls(car_data.car_key)
for i, img_url in enumerate(fallback_urls):
local_filename = f"image_{i}.jpg"
local_path = f"{image_base_dir}/{local_filename}"
if await download_image(img_url, local_path):
car_image = CarImage(
car_id=car.id,
url=f"/uploads/cars/{car.id}/{local_filename}",
local_path=local_path,
is_main=(i == 0),
sort_order=i
)
db.add(car_image)
downloaded_images.append(local_filename)
print(f"[Image Fallback] Downloaded {len(downloaded_images)} images via AutoDB for car {car.id}")
# 성능점검표 가져오기 (check_num이 있으면 직접 사용)
perf_check_result = await carmodoo_client.get_performance_check(
car_data.car_no,