Membuat Skrip Python untuk Mengunduh Ratusan Logo SVG ke PNG

Saya sedang mengerjakan sebuah proyek, membuat landing page untuk menampilkan daftar saham dari bursa AS. Agar tampilannya menarik, setiap saham perlu dilengkapi dengan logo perusahaannya.

Sumber logo terbaik yang saya temukan adalah dari TradingView. Masalahnya, saya belum punya kemampuan untuk membuat sistem yang bisa mengambil logo secara otomatis via API. Pilihan satu-satunya adalah mengunduh manual, dan ternyata semua logo disediakan dalam format SVG, padahal saya butuh PNG untuk diunggah ke landing page.

Membayangkan harus mengunduh ratusan logo satu per satu lalu mengonversinya membuat saya pusing. Di situlah saya memutuskan untuk membuat skrip Python sendiri.

Hal yang Perlu Disiapkan

Sebelum mulai membuat kode, ini adalah beberapa hal mendasar yang saya siapkan terlebih dahulu sebagai fondasi.

Pertama, Python 3 harus sudah terpasang di sistem. Kedua, semua interaksi perintah dijalankan melalui Terminal di macOS.

Terakhir, saya menyiapkan sebuah file teks bernama kumpulanlogo.txt. Di dalam file ini, saya menempelkan semua URL SVG yang ingin diunduh, dengan format satu URL per baris.

kumpulanlogo

Instalasi Library yang Dibutuhkan

Untuk membuat skrip ini, saya memerlukan beberapa library Python untuk mempermudah pekerjaan.

  • requests: Berguna untuk berkomunikasi dengan internet dan mengunduh konten dari sebuah URL.
  • cairosvg: Alat yang sangat andal untuk mengubah data SVG menjadi format PNG.

Perintah untuk memasang keduanya adalah sebagai berikut.

pip install requests cairosvg

Saat proses ini, saya sempat menemukan kendala di macOS. cairosvg ternyata memerlukan sebuah program sistem terpisah bernama Cairo. Jika muncul error yang menyebutkan cairo tidak ditemukan, solusinya adalah memasang dependensi sistem tersebut menggunakan Homebrew.

brew install cairo

Setelah ini terpasang, semua komponen yang dibutuhkan oleh skrip sudah siap.

Arsitektur Kode yang Dibuat

Langkah pertama adalah menyusun kerangka kode. Saya membuat sebuah file baru bernama unduh_konversi.py.

Sebagai praktik yang baik, semua bagian yang mungkin perlu diubah di masa depan (konfigurasi) saya letakkan di bagian paling atas. Ini membuat skrip lebih mudah dikelola.

import os
import requests
import cairosvg
from concurrent.futures import ThreadPoolExecutor
from urllib.parse import urlparse

# --- Konfigurasi ---
URL_FILE = 'logopertama.txt'
OUTPUT_DIR = 'hasil_png'
MAX_WORKERS = 10

Di sini, saya mengimpor semua library yang dibutuhkan dan mendefinisikan tiga variabel: nama file sumber URL, nama folder untuk menyimpan hasil, dan jumlah unduhan simultan yang akan dijalankan.

Logika Inti untuk Memproses Setiap URL

Inti dari skrip ini adalah sebuah fungsi yang bertugas memproses satu URL. Dengan memisahkannya ke dalam fungsi, kode menjadi lebih bersih dan terstruktur.

Fungsi ini melakukan beberapa hal secara berurutan: mengekstrak nama file yang bersih, memeriksa apakah file sudah ada, mengunduh data SVG, dan terakhir mengonversinya ke PNG.

def process_url(url):
    try:
        # Ekstrak nama file dari URL
        filename_base = os.path.splitext(os.path.basename(urlparse(url).path))[0]
        output_png_path = os.path.join(OUTPUT_DIR, f"{filename_base}.png")

        # Lewati jika file sudah ada
        if os.path.exists(output_png_path):
            print(f"🟡 File {filename_base}.png sudah ada, dilewati.")
            return

        # Unduh konten SVG
        response = requests.get(url, timeout=20)
        response.raise_for_status()
        svg_content = response.content

        # Konversi dan simpan sebagai PNG
        cairosvg.svg2png(bytestring=svg_content, write_to=output_png_path)
        print(f"✅ Berhasil: {url} -> {filename_base}.png")

    except Exception as e:
        print(f"❌ Gagal memproses {url}: {e}")

Penggunaan try…except sangat penting di sini. Blok ini berfungsi sebagai jaring pengaman untuk menangkap masalah seperti URL yang tidak valid atau koneksi internet yang terputus, sehingga skrip tidak berhenti di tengah jalan.

Akselerasi Proses dengan Eksekusi Paralel

Jika ada ribuan URL, memprosesnya satu per satu akan tetap memakan waktu. Agar prosesnya cepat, saya memanfaatkan pemrosesan paralel.

Idenya adalah seperti memiliki 10 kasir yang melayani 10 antrean sekaligus, bukan hanya satu. Saya menggunakan ThreadPoolExecutor untuk menjalankan fungsi process_url untuk banyak URL secara bersamaan.

# Baca semua URL dari file
with open(URL_FILE, 'r') as f:
    urls = [line.strip() for line in f if line.strip()]

# Jalankan proses secara paralel
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
    executor.map(process_url, urls)

Dengan beberapa baris kode ini, proses yang tadinya sekuensial menjadi jauh lebih cepat dan efisien.

Kode Lengkap dan Cara Menjalankannya

Setelah semua bagian digabungkan, berikut adalah kode lengkap dari skrip unduh_konversi.py yang saya buat.

import os
import requests
import cairosvg
from concurrent.futures import ThreadPoolExecutor
from urllib.parse import urlparse

# --- Konfigurasi ---
URL_FILE = 'logopertama.txt'
OUTPUT_DIR = 'hasil_png'
MAX_WORKERS = 10

# Membuat folder output jika belum ada
if not os.path.exists(OUTPUT_DIR):
    os.makedirs(OUTPUT_DIR)

def get_filename_from_url(url):
    """Mengekstrak nama file yang bersih dari URL."""
    try:
        path = urlparse(url).path
        filename_with_ext = os.path.basename(path)
        return os.path.splitext(filename_with_ext)[0]
    except Exception:
        return None

def process_url(url):
    """Fungsi untuk mengunduh, mengonversi, dan menyimpan satu gambar."""
    try:
        filename_base = get_filename_from_url(url)
        if not filename_base:
            print(f"❌ Gagal mendapatkan nama file dari URL: {url}")
            return

        output_png_path = os.path.join(OUTPUT_DIR, f"{filename_base}.png")

        if os.path.exists(output_png_path):
            print(f"🟡 File {filename_base}.png sudah ada, dilewati.")
            return

        response = requests.get(url, timeout=20)
        response.raise_for_status()
        svg_content = response.content

        cairosvg.svg2png(bytestring=svg_content, write_to=output_png_path)
        print(f"✅ Berhasil: {url} -> {filename_base}.png")

    except requests.exceptions.RequestException as e:
        print(f"❌ Gagal mengunduh {url}: {e}")
    except Exception as e:
        print(f"❌ Terjadi error saat memproses {url}: {e}")

# --- Proses Utama ---
if __name__ == "__main__":
    print(f"🚀 Memulai proses dari file '{URL_FILE}'...")
    
    try:
        with open(URL_FILE, 'r') as f:
            urls = [line.strip() for line in f if line.strip()]
    except FileNotFoundError:
        print(f"🚨 FATAL: File '{URL_FILE}' tidak ditemukan!")
        exit()

    with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
        executor.map(process_url, urls)

    print("\n✨ --- Proses Selesai --- ✨")
    print(f"Semua file PNG yang berhasil diunduh tersimpan di folder: '{OUTPUT_DIR}'")

Cara menjalankan skripnya adalah dengan membuka Terminal, navigasi ke folder tempat file disimpan, dan mengetik perintah:

python3 unduh_konversi.py

Setelah dijalankan, proses akan berjalan di terminal dan sebuah folder baru bernama hasil_png akan terisi dengan semua gambar yang dibutuhkan.

Pada akhirnya, skrip ini berhasil menghemat banyak waktu saya dan menyelesaikan masalah untuk proyek landing page tersebut.

Dokumentasi ini saya buat sebagai catatan untuk masa depan, barangkali perlu melakukan hal serupa atau ingin mengembangkannya lebih jauh. Beberapa ide pengembangan misalnya menambahkan progress bar dengan tqdm atau membaca URL dari file Excel dengan pandas.

Beberapa dokumentasi yang membantu saya menyelesaikan analisis ini antara lain:

Published by rendyandriyanto

Your go-to SEO Specialist. Passionate about achieving growth in digital marketing and financial markets.

Leave a comment

Your email address will not be published. Required fields are marked *