Zendesk 커뮤니티에서 이미지를 내보내는 Python 스크립트

Zendesk 커뮤니티에서 Discourse로 이미지를 마이그레이션해야 하는 경우? Python 스크립트 제공!

안녕하세요 여러분,

저는 Zendesk 커뮤니티를 Discourse로 마이그레이션하는 작업을 진행하다가 짜증스러운 문제에 부딪혔습니다. 바로 Zendesk에서 이미지를 내보내는 것이었죠. 문제는 무엇이었을까요? Zendesk의 CDN은 직접적으로 몇 장의 이미지를 가져온 뒤 접근을 차단하기 시작하여, 일괄 다운로드가 정말 어려운 과제가 되었습니다.

여러 가지 방법을 시도한 끝에, 저는 이 제한을 우회하는 Python 스크립트(AI의 도움으로 작성)를 만들었습니다. 이 스크립트는 Selenium을 사용하여 브라우저에서 각 이미지 URL을 열고, 이미지의 스크린샷을 찍은 후 로컬에 저장합니다. 이미지를 직접 다운로드하는 것만큼 깔끔하지는 않지만, 안정적으로 작동하며 이미지는 고품질로 나옵니다.

비슷한 마이그레이션 작업을 하고 계신 분들에게 이 글이 도움이 되기를 바랍니다!


필요한 준비물

  1. Python: 설치되어 있고 사용 가능한 상태여야 합니다.
  2. ChromeDriver:
    Chrome for Testing에서 다운로드하여 압축을 풀고, 스크립트에 드라이버의 경로를 업데이트하세요.
  3. CSV 파일:
  • URL이라는 이름의 컬럼이 하나 있는 CSV 파일을 생성하세요.
  • Zendesk에서 내보내려는 이미지의 직접 URL로 채우세요.
  • 스크립트에 이 파일의 경로를 업데이트하세요.
  1. 저장 위치:
    이미지를 저장하려는 폴더의 경로를 스크립트에 업데이트하세요.

마지막으로, 몇 가지 Python 라이브러리를 설치해야 합니다:

pip install selenium pillow

스크립트

아래는 Python 스크립트입니다. 설정에 맞게 자유롭게 수정해 보세요:

import csv
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
from PIL import Image
import io
import re
import os

# URL에서 이미지 ID를 추출하는 함수
def extract_image_id(url):
    match = re.search(r'/([^/]+)\.(png|jpg|jpeg|gif)$', url, re.IGNORECASE)
    if match:
        return match.group(1)
    return 'image'

# URL에서 이미지를 다운로드하고 저장하는 함수
def download_image(driver, image_url, download_folder):
    driver.get(image_url)
    
    # 이미지가 로드될 때까지 대기
    wait = WebDriverWait(driver, 20)
    img_element = wait.until(EC.presence_of_element_located((By.TAG_NAME, 'img')))

    # 이미지 요소의 위치와 크기 가져오기
    location = img_element.location
    size = img_element.size

    # 전체 페이지의 스크린샷 찍기
    screenshot = driver.get_screenshot_as_png()
    
    # 스크린샷을 PIL Image로 변환
    screenshot_image = Image.open(io.BytesIO(screenshot))

    # 이미지의 바운딩 박스 정의 (왼쪽, 위쪽, 오른쪽, 아래쪽)
    left = location['x']
    top = location['y']
    right = left + size['width']
    bottom = top + size['height']
    bbox = (left, top, right, bottom)

    # 바운딩 박스에 맞게 이미지 크롭
    cropped_image = screenshot_image.crop(bbox)

    # URL에서 이미지 ID 추출
    image_id = extract_image_id(image_url)

    # 이미지 ID를 파일명으로 하여 다운로드 폴더에 크롭된 이미지 저장
    cropped_image.save(os.path.join(download_folder, f'{image_id}.png'))

# CSV 파일에서 URL을 로드하는 함수
def load_urls_from_csv(csv_file):
    urls = []
    with open(csv_file, mode='r', newline='', encoding='utf-8') as file:
        reader = csv.DictReader(file)
        for row in reader:
            urls.append(row['URL'])  # CSV에 'id'와 'url' 컬럼이 있다고 가정
    return urls

# ChromeDriver 서비스 설정
service = Service("C:\\Users\\tslam\\Downloads\\chromedriver-win64\\chromedriver-win64\\chromedriver.exe")
driver = webdriver.Chrome(service=service)

try:

    # 브라우저 창을 전체 화면으로 최대화
    driver.maximize_window()
    
    # CSV 파일에서 URL 로드
    csv_file = 'C:\\Users\\tslam\\Zendesk Migration\\image_urls.csv'
    image_urls = load_urls_from_csv(csv_file)
    
    # 다운로드 폴더 경로 정의
    download_folder = 'C:\\Users\\tslam\\Zendesk Migration\\downloads'
    
    # 다운로드 폴더가 존재하는지 확인
    if not os.path.exists(download_folder):
        os.makedirs(download_folder)

    # 각 이미지 URL 처리
    for url in image_urls:
        download_image(driver, url, download_folder)

finally:
    driver.quit()

좋네요! 이 방법은 Zendesk만이 아니라 동일한 문제에 직면한 다른 마이그레이션에도 활용할 수 있습니다. 공유해 주셔서 정말 감사합니다.