Tôi Đã Xây Dựng Một Công Cụ Để Chuyển Đổi 500+ Hình Ảnh Sang WebP Trong Một Giờ
Điểm Lighthouse của tôi đang khóc vì những hình ảnh nặng. Vì vậy, tôi đã viết một ETL Python để chuyển đổi hàng loạt mọi thứ sang WebP và cập nhật tất cả các URL tự động. Đây là cách.
Tôi đang nhìn chằm chằm vào báo cáo Lighthouse của mình như thể nó nợ tôi tiền.
Hiệu suất: 62.
Thủ phạm? Hình ảnh. Hàng trăm hình ảnh rải rác trong các tệp markdown, được lưu trữ trên Flickr, Imgur, GitHub… tất cả ở định dạng JPEG và PNG chưa được tối ưu hóa.
Cách sửa thủ công sẽ là:
- Tải xuống từng hình ảnh
- Chuyển đổi sang WebP
- Tải lên CDN của tôi
- Tìm và thay thế mọi URL trong mọi tệp markdown
Với 500 hình ảnh duy nhất? Đó không phải là dự án cuối tuần. Đó là án tù.
Vì vậy, tôi đã làm điều mà bất kỳ kỹ sư lười biếng nào cũng làm: Tôi tự động hóa nó.
Vấn Đề
Blog của tôi sử dụng Hugo với các tệp markdown. Hình ảnh được tham chiếu ở khắp nơi:
# Trong frontmatter
image: "https://live.staticflickr.com/65535/54519397357_403fc67f4a_k. jpg"
# Trong shortcodes gallery
< gallery id="example_id">
- https://live.staticflickr.com/65535/54525108024_adbff3cc9b_k. jpg
- https://live.staticflickr.com/65535/54520449879_784f0f24ca_k. jpg
< /gallery >
# Markdown tiêu chuẩn

Mỗi hình ảnh phải được:
- Tải xuống từ nguồn gốc
- Chuyển đổi sang WebP (nhỏ hơn, nhanh hơn)
- Tải lên CDN mới của tôi
- URL được thay thế trong tệp markdown
Nhân với 500. Không cảm ơn.
Giải Pháp: Pipeline ETL
Tôi đã xây dựng bulk-webp-url-replacer—một công cụ Python làm chính xác những gì nó nói:
python -m bulk_webp_url_replacer \
--scan-dir ./content \
--download-dir ./downloads \
--output-dir ./webp_images \
--new-url-prefix "https://cdn.example.com/images" \
--threads 8
Nó làm gì:
- Extract — Quét tất cả tệp
.mdđể tìm URL hình ảnh (frontmatter, galleries, inline) - Transform — Tải xuống từng hình ảnh và chuyển đổi sang WebP
- Load — Thay thế tất cả URL cũ bằng đường dẫn CDN mới
Một lệnh. 500 hình ảnh. Xong.
Các Chi Tiết Kỹ Thuật
Mẫu Regex Để Trích Xuất URL
Markdown có nhiều cách nhúng hình ảnh. Trình trích xuất của tôi xử lý tất cả:
PATTERNS = [
# YAML frontmatter: image: "https://..."
re.compile(r'^image:\s*["\']?(https?://[^"\'>\s]+)["\']?\s*$'),
# TOML frontmatter: image = "https://..."
re.compile(r'^image\s*=\s*["\']?(https?://[^"\'>\s]+)["\']?\s*$'),
# Gallery shortcodes: - https://...
re.compile(r'^\s*-\s+(https?://[^\s]+\.(jpg|jpeg|png|gif|webp))\s*$'),
# Standard markdown: <img src="https://..." alt="alt" loading="lazy" decoding="async" />
re.compile(r'!\[[^\]]*\]\((https?://[^)]+)\)'),
]
Tải Xuống Song Song
Tải xuống 500 hình ảnh tuần tự? Chậm. Với ThreadPoolExecutor:
with ThreadPoolExecutor(max_workers=8) as executor:
futures = {executor.submit(process_url, url): url for url in urls}
for future in as_completed(futures):
# Process results as they complete
8 luồng = nhanh hơn 8 lần. Toán học đơn giản.
Giới Hạn Tốc Độ & Thử Lại
Imgur không vui với sự nhiệt tình của tôi. Lỗi HTTP 429 khắp nơi.
Cách sửa: backoff theo cấp số nhân với headers giống trình duyệt.
HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
}
for attempt in range(max_retries):
response = requests.get(url, headers=HEADERS, timeout=30)
if response.status_code == 429:
time.sleep(2 ** attempt) # 1s, 2s, 4s...
continue
Bỏ Qua Thông Minh
Công cụ lưu mapping.json sau mỗi lần chạy:
{
"https://old-url.com/image.jpg": "new-filename.webp"
}
Lần chạy tiếp theo? Nó bỏ qua các hình ảnh đã xử lý. Di chuyển gia tăng FTW.
Kết Quả
Trước:
- 612 tham chiếu hình ảnh trên 72 tệp markdown
- Hình ảnh rải rác trên Flickr, Imgur, GitHub
- Lighthouse van xin lòng thương
Sau:
- Tất cả hình ảnh được chuyển đổi sang WebP
- Được lưu trữ trên một CDN duy nhất
- URL được cập nhật tự động
- Một giờ làm việc (chủ yếu xem thanh tiến trình)
Cải thiện hiệu suất:
- Kích thước hình ảnh trung bình: nhỏ hơn 60-80%
- Hiệu suất Lighthouse: 62 → 89
Bài Học Rút Ra
-
Tự động hóa mở rộng. Những gì mất vài ngày thủ công chỉ mất một giờ để xây dựng và vài phút để chạy.
-
Giới hạn tốc độ là thực tế. Luôn thêm thử lại và backoff. Các trang như Imgur sẽ hạn chế bạn.
-
Chạy thử trước. Cờ
--dry-runđã cứu tôi khỏi vô tình phá hỏng 72 tệp. -
WebP đáng giá. Chất lượng giống nhau, kích thước nhỏ hơn nhiều. Không có lý do gì để phục vụ JPEG vào năm 2026.
Hãy Tự Thử
Công cụ mã nguồn mở trên GitHub.
# Xem trước những gì sẽ thay đổi
bulk-webp-url-replacer \
--scan-dir ./content \
--download-dir ./downloads \
--output-dir ./webp \
--dry-run
# Chạy thực sự
bulk-webp-url-replacer \
--scan-dir ./content \
--download-dir ./downloads \
--output-dir ./webp \
--new-url-prefix "https://your-cdn.com/images" \
--threads 8
Điểm Lighthouse của bạn sẽ cảm ơn bạn. 🚀
Ví Dụ Đầu Ra
Sau khi chạy công cụ di chuyển, các URL được cập nhật tự động để trỏ đến các phiên bản WebP được tối ưu hóa:
# Trong frontmatter
image: "https://raw.githubusercontent.com/HoangGeek/store/refs/heads/main/webp/54519397357_403fc67f4a_k.webp"
# Trong shortcodes gallery
< gallery id="example_id">
- https://raw.githubusercontent.com/HoangGeek/store/refs/heads/main/webp/54525108024_adbff3cc9b_k.webp
- https://raw.githubusercontent.com/HoangGeek/store/refs/heads/main/webp/54520449879_784f0f24ca_k.webp
< /gallery >
# Markdown tiêu chuẩn
<img src="https://raw.githubusercontent.com/HoangGeek/store/refs/heads/main/webp/sXyG3GX.webp" alt="Ảnh của tôi" loading="lazy" decoding="async" /> Bài viết liên quan
-
MoneyPrinterV2: 18.000 Sao GitHub Và Cái Máy In Nội Dung Tự Động
Ollama viết kịch bản, KittenTTS đọc, Gemini vẽ hình, MoviePy ghép video. Bạn ngồi uống cà phê. YouTube Short tự lên kênh.
-
Giải Mã Super Agent Harness: Đi Sâu Vào DeerFlow Của Bytedance
Khám phá cách DeerFlow 2.0 chuyển mình từ một công cụ nghiên cứu chuyên sâu thành một hệ sinh thái agent toàn diện với sandbox, sub-agent và bộ nhớ dài hạn.
-
Giải thích về OpenBB: Nền tảng Dữ liệu Mở cho Nghiên cứu Đầu tư
Phân tích sâu về OpenBB, nền tảng mã nguồn mở giúp thống nhất các API dữ liệu tài chính thành một giao diện duy nhất cho lập trình viên Python, nhà phân tích và các AI agents.
-
5 Dự Án Tuyệt Vời Có Thể Làm Với LM Studio Local API
Hướng dẫn cách sử dụng Local Server của LM Studio với script Python, AI coding assistant, và chat với tài liệu bảo mật hoàn toàn miễn phí.