A zero-dependency Python CLI tool that reads image URLs from a CSV file and downloads them all into a local folder.
- Auto-detects the URL column — no need to specify it manually if column names are standard (
url,image,link,src,href, …) - Retries on failure — each URL is retried up to 3 times before being marked as failed
- Skips duplicates — avoids re-downloading the same URL twice
- Safe filenames — sanitizes filenames automatically; appends a counter if a name conflicts
- No external libraries — uses only Python's standard library (
csv,urllib,pathlib, …) - Supports
.jpg,.jpeg,.png,.gif,.webp,.bmp,.svg,.tiff
# Auto-detect the URL column
python main.py data.csv
# Specify the column name explicitly
python main.py data.csv image_url
# Custom output folder
python main.py data.csv image_url --output my_photos| Argument | Required | Description |
|---|---|---|
csv_file |
✅ | Path to the CSV file |
column |
❌ | Column name containing the URLs (auto-detected if omitted) |
--output / -o |
❌ | Output folder (default: images) |
Your CSV just needs one column with image URLs. Everything else is ignored.
id,name,image_url
1,sunset,https://example.com/photos/sunset.jpg
2,mountain,https://example.com/photos/mountain.png
3,ocean,https://example.com/photos/ocean.webp- Python 3.10+
- No external packages needed
You can tweak the constants at the top of main.py:
| Variable | Default | Description |
|---|---|---|
OUTPUT_DIR |
images |
Default output folder |
TIMEOUT |
15 |
Request timeout in seconds |
DELAY |
0.3 |
Delay between requests (seconds) |
MAX_RETRIES |
3 |
Max retry attempts per URL |
📂 Output folder : /home/user/project/images
📋 Column used : image_url
🔗 Total URLs : 120
[1/120] ✓ 0001_sunset.jpg (84,231 bytes)
[2/120] ✓ 0002_mountain.png (210,540 bytes)
[3/120] ✗ https://broken-link.com/photo.jpg — HTTP 404
...
──────────────────────────────────────────────────
✅ Success : 117
❌ Failed : 2
⤼ Skipped : 1
📁 Saved to: /home/user/project/images
csv-image-downloader/
├── main.py # main script
├── README.md
└── images/ # created automatically on first run
MIT