Скрейпинг изображений на Python с помощью BeautifulSoup

Введение
Скрейпинг изображений на Python — это полезный навык: его можно применять для подготовки датасетов для машинного обучения, генерации миниатюр для сайтов или массовой загрузки ресурсов для офлайн‑архивации. Вы получите полный контроль над процессом, если построите инструмент самостоятельно.
В этом руководстве показано, как безопасно и корректно извлечь URL изображений со страницы, преобразовать относительные пути в абсолютные и скачать файлы в папку проекта.
TL;DR (коротко)
- Проверяйте /robots.txt и лицензию на изображения перед повторным использованием.
- Используйте requests для HTTP‑запросов и BeautifulSoup для парсинга.
- Преобразуйте относительные URL в абсолютные с помощью requests.compat.urljoin.
- Защищайте процесс: соблюдайте задержки между запросами, обрабатывайте ошибки и избегайте перезаписи файлов.
Законно ли скачивать изображения?
Как и общий веб‑скрейпинг, скачивание изображений само по себе не является автоматически незаконным. Однако соблюдайте следующие правила:
- Проверьте файл /robots.txt на сайте — он указывает, какие части сайта разрешено обходить.
- Уважайте лицензионные условия: наличие публичного доступа к файлу не означает разрешения на повторное использование.
- Не используйте автоматически скачанные изображения для коммерческого перепубликации без явного права.
Важно: если вы обрабатываете персональные данные или изображения, где можно идентифицировать людей, учтите требования местного законодательства о защите персональных данных (например, GDPR в ЕС). См. раздел «Конфиденциальность и соответствие» ниже.
Установка пакетов Python
Создайте виртуальное окружение и установите зависимости:
pip install bs4 requestsЕсли Python ещё не установлен, скачайте его с официального сайта https://python.org.
Как извлечь URL изображений с помощью BeautifulSoup
- Создайте файл с расширением .py в корне проекта.
- Выполняйте фрагменты кода по шагам — каждый следующий блок строится на предыдущем.
Пример запроса страницы и проверки кода ответа:
import requests
URL = "https://example.com" # Замените на адрес целевого сайта
response = requests.get(URL, headers={"User-Agent": "Mozilla/5.0"})
print(response.status_code) # 200 означает успехЕсли вы получили код 200, продолжайте. В противном случае проверьте сеть и корректность URL.
Парсинг HTML и поиск тэгов img:
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
images = soup.find_all('img')
print(f"Найдено изображений: {len(images)}")Извлечение значений атрибутов src:
image_sources = []
for img in images:
src = img.get('src')
if src: # некоторые теги img могут не иметь src
image_sources.append(src)
print(image_sources)Теперь у вас есть список ссылок, но они могут быть относительными.
Как сохранить изображения на диск
Создайте папку в корне проекта с именем images (или любое другое). Для корректной загрузки пути должны быть абсолютными: содержать схему http/https и домен. Используйте requests.compat.urljoin для преобразования относительных ссылок:
from bs4 import BeautifulSoup
import requests
import os
from urllib.parse import urlparse
import uuid
import time
URL = "https://example.com" # Замените
response = requests.get(URL, headers={"User-Agent": "Mozilla/5.0"})
soup = BeautifulSoup(response.text, 'html.parser')
images = soup.find_all('img')
os.makedirs('images', exist_ok=True)
resolved_urls = []
for img in images:
src = img.get('src')
if not src:
continue
full_url = requests.compat.urljoin(URL, src)
resolved_urls.append(full_url)
# Простая логика скачивания с защитой от перезаписи
for url in resolved_urls:
try:
r = requests.get(url, headers={"User-Agent": "Mozilla/5.0"}, stream=True, timeout=10)
if r.status_code == 200:
# используем оригинальное имя файла, если возможно
filename = os.path.basename(urlparse(url).path)
if not filename: # если имя пустое
filename = str(uuid.uuid4()) + '.jpg'
dest = os.path.join('images', filename)
# избегаем перезаписи: добавляем суффикс при необходимости
base, ext = os.path.splitext(dest)
counter = 1
while os.path.exists(dest):
dest = f"{base}_{counter}{ext}"
counter += 1
with open(dest, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
time.sleep(0.5) # уважительная задержка между запросами
else:
print(f"Не удалось скачать {url}: код {r.status_code}")
except Exception as e:
print(f"Ошибка при скачивании {url}: {e}")Этот скрипт:
- Преобразует относительные URL в абсолютные.
- Скачивает файлы потоково (stream=True).
- Избегает перезаписи, добавляя суффикс, если имя уже существует.
- Добавляет небольшую задержку между запросами, чтобы снизить нагрузку на сервер.
Советы по надёжности и производительности
- Ограничивайте скорость запросов (rate limiting) и добавляйте случайную задержку, чтобы не выглядеть как бот.
- Реализуйте повторные попытки (retries) для временных ошибок сети.
- Используйте сессии requests.Session() для повторного использования TCP‑соединений.
- Для больших объёмов данных рассмотрите параллельные загрузки с контролем количества одновременных соединений.
Примеры альтернативных подходов
- API сайта: многие сервисы предлагают официальные API для получения изображений — это предпочтительный и правомерный путь.
- RSS/Atom‑ленты: иногда содержат прямые ссылки на изображения.
- Публичные датасеты: для ML‑задач используйте готовые наборы изображений (ImageNet, COCO и т.д.) вместо парсинга сайтов.
- Selenium / Playwright: если изображения загружаются динамически (через JS), используйте браузерный автоматизированный запуск.
Когда скрейпинг изображений не подойдёт (контрпример)
- Если сайт явно запрещает автоматические запросы в Terms of Service.
- Если изображения защищены DRM или подлинники доступны только после авторизации с ограничением прав.
- Если вам нужны гарантии прав на дальнейшее коммерческое использование — API или лицензированные датасеты предпочтительнее.
Ментальные модели и эвристики
- «Чайник‑правило»: начинайте с малого — одна страница, одна папка, проверьте результат, затем масштабируйте.
- «Минимально необходимый запрос»: получайте только то, что нужно — избегайте загрузки огромных страниц и лишних ресурсов.
- «Будь вежлив»: задержки, корректный User‑Agent, лимиты запросов.
Мини‑методология: быстрый чеклист действий
- Проверить /robots.txt и условия использования.
- Собрать список целевых URL страниц.
- Для каждой страницы: получить HTML → найти img → разрешить URL → скачать и сохранить.
- Вести лог ошибок и пропущенных файлов.
- Проверить правовой статус изображений перед повторным использованием.
Роль‑ориентированные контрольные списки
Для разработчика:
- Настроил виртуальное окружение и зависимости.
- Реализовал обработку ошибок и повторные попытки.
- Добавил задержки и контроль одновременных запросов.
Для дата‑саентиста:
- Проверил формат и разрешение изображений.
- Вычислил баланс классов в датасете.
- Убедился, что метаданные сохранены (источник, URL).
Для юриста/ответственного по соответствию:
- Проверил лицензии и лицензионные ограничения.
- Оценил риски использования изображений в проекте.
Критерии приёмки
- Скрипт скачивает все валидные изображения со страницы и сохраняет их в папку images.
- Нет перезаписи уже существующих файлов (суффиксы добавляются при коллизиях).
- Скрипт корректно обрабатывает относительные и абсолютные URL.
- Логируются ошибки скачивания и коды ответов.
Тесты и сценарии приёма
- Страница с абсолютными URL: все изображения скачаны.
- Страница с относительными URL: ссылки правильно разрешены и скачаны.
- Отсутствие src у img: теги пропускаются без падения скрипта.
- Неверный URL: формируется сообщение об ошибке и продолжается обработка остальных изображений.
Риск‑матрица и смягчение рисков
- Риск: блокировка по IP за высокую частоту запросов. Смягчение: добавить задержки, использовать прокси, распределённые агенты.
- Риск: нарушение авторских прав. Смягчение: перед использованием проверять лицензию, использовать только для внутренней подготовки данных.
- Риск: повреждённые или частично скачанные файлы. Смягчение: проверять размер и MIME‑тип, сохранять временно и переименовывать после валидации.
Безопасность и конфиденциальность
- Не загружайте и не сохраняйте изображения с личными данными без юридической оценки.
- Храните логи и скачанные файлы в безопасном месте с контролем прав доступа.
- Удаляйте ненужные временные файлы и очищайте сессии после завершения.
Советы по масштабированию и миграции
- Для проектов с большим объёмом изображений используйте объектное хранилище (S3, MinIO).
- Разделите этапы: сбор URL → валидация → скачивание → обработка.
- Для динамически генерируемых страниц используйте headless‑браузеры и кэширование.
Факто‑бокс: ключевые моменты
- Основные пакеты: requests и BeautifulSoup (bs4).
- Обязательная проверка: /robots.txt и лицензия изображений.
- Типичный HTTP‑код успеха: 200 OK.
- Рекомендуемая задержка между запросами: от 0.2 до 2 секунд (в зависимости от нагрузки на сайт).
Частые крайние случаи и как с ними справляться
- Относительные пути, содержащие протокол‑отсутствует (“//example.com/image.jpg”): urljoin корректно их обработает.
- Lazy‑loading изображений: ищите атрибуты data‑src или srcset и дополняйте логику.
- Файлы без расширения: определяйте MIME‑тип из заголовка Content‑Type и добавляйте соответствующее расширение.
Краткий чек‑лист безопасности и соответствия (локализация для РФ и ЕС)
- Убедитесь, что для изображений с идентифицируемыми людьми получено необходимое согласие.
- Для коммерческого использования уточните авторские права владельца изображения.
- Хранение персональных данных и метаданных должно соответствовать GDPR/ФЗ‑152, если применимо.
Заключение
Скрейпинг изображений на Python — мощный инструмент при правильном и ответственном применении. Начните с простого скрипта, проверяйте правила сайта и лицензии изображений, добавляйте обработку ошибок, и масштабируйте процесс постепенно. Соблюдение этики и требований соответствия не менее важно, чем техническая корректность.
Важно: если вы планируете использовать скачанные изображения вне личного/внутреннего тестирования, проконсультируйтесь с юристом по авторскому праву.
Краткий план действий, если нужно объявить обновление инструмента команде (анонс):
Мы реализовали скрипт для массового скачивания изображений с веб‑страниц на Python. Скрипт поддерживает преобразование относительных ссылок, защиту от перезаписи файлов и базовую обработку ошибок. Перед использованием проверьте лицензии и правила источника.
Похожие материалы
Ноутбук не подключается к хотспоту — как исправить
Выбор данных для синхронизации в Google Chrome
Как изменить разрешения внешнего диска в Windows
Как сравнить файлы в Linux с помощью diff
Быстрые действия Outlook: настройка и советы