© 2026 IT_БЛОГ
WEB-разработчика
и SEO-оптимизатора Анны Елисеевой

Год назад я открыла для себя Python, и с тех пор он уверенно вошёл в список моих фаворитов.

Несмотря на большую занятость, я всё равно понемногу его изучаю, практикуюсь и стараюсь внедрять в реальные рабочие задачи. И чем дальше, тем больше понимаю: Python — это не просто «язык для программистов», а очень полезный рабочий инструмент, который может экономить часы рутины и закрывать вполне прикладные задачи буквально в несколько команд.

Одна из таких задач — выгрузка изображений с сайта. Причём не просто картинок со страницы, а именно полноразмерных файлов, а не миниатюр и не превью, которые потом годятся только для очень грустного использования.


Ниже — практический материал о том, как можно решить такую задачу с помощью двух Python-скриптов: сначала простого, а потом доработанного под выгрузку изображений в максимальном размере.

Когда это реально нужно

Такая задача встречается чаще, чем кажется. Например:

  • нужно быстро собрать фотографии проектов с сайта заказчика;
  • нужно выгрузить изображения товаров или кейсов для дальнейшей работы;
  • нужно сохранить медиаматериалы перед переделкой сайта;
  • нужно получить не уменьшенные версии, а исходники фотографий.

На практике проблема обычно выглядит так: открываешь страницу, видишь хорошие изображения, запускаешь базовую выгрузку — а скрипт скачивает маленькие версии файлов. Вроде картинки есть, но использовать их нормально уже нельзя.

Как создавалось программное решение

Мне нравится в Python именно то, что проект можно наращивать поэтапно.

  1. Сначала делается простой рабочий вариант, который решает задачу хотя бы базово.
  2. Потом проверяется результат на реальной странице.
  3. После этого находятся ограничения.
  4. И уже затем скрипт дорабатывается под более умную логику.

Именно так получилось и здесь. Сначала нужен был обычный скрипт, который просто скачивает изображения со страницы. Он сработал. Но потом выяснилось, что скачиваются не те размеры, которые нужны. Тогда появился второй вариант — скрипт для выгрузки максимально крупных изображений.

Скрипт №1: базовая выгрузка изображений

Первый вариант подойдёт, если нужно быстро скачать все изображения, которые видны в HTML страницы.

Что делает этот скрипт:

  • отправляет запрос к странице;
  • разбирает HTML через BeautifulSoup;
  • находит теги <img>;
  • собирает ссылки на изображения;
  • сохраняет файлы в указанную папку.

Код скрипта:

import os
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin


def download_images(url, save_folder='images'):
    if not os.path.exists(save_folder):
        os.makedirs(save_folder)

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36'
    }

    response = requests.get(url, headers=headers)
    response.raise_for_status()

    soup = BeautifulSoup(response.text, 'html.parser')
    img_tags = soup.find_all('img')

    print(f'Найдено изображений: {len(img_tags)}')

    for i, img in enumerate(img_tags, 1):
        img_url = img.get('src')
        if not img_url:
            continue

        img_url = urljoin(url, img_url)
        filename = os.path.basename(img_url.split('?')[0]) or f'image_{i}.jpg'
        filepath = os.path.join(save_folder, filename)

        try:
            img_data = requests.get(img_url, headers=headers)
            img_data.raise_for_status()

            with open(filepath, 'wb') as f:
                f.write(img_data.content)

            print(f'[{i}] Сохранено: {filename}')
        except Exception as e:
            print(f'[{i}] Ошибка загрузки {img_url}: {e}')


if __name__ == '__main__':
    url = input('Введите URL страницы: ').strip()
    folder = input('Введите папку для сохранения (Enter = images): ').strip() or 'images'
    download_images(url, folder)

Как запустить:

  1. Сохраните код в файл simple_image_downloader.py.
  2. В терминале выполните:
python simple_image_downloader.py
  1. Введите URL страницы.
  2. Укажите папку для сохранения или оставьте пустое поле — тогда будет использована папка images.

Когда этот вариант хорош:

  • если нужно просто быстро собрать все изображения со страницы;
  • если сайт не использует сложную механику подстановки изображений;
  • если размер файлов не критичен.

Где он ограничен: если на сайте используются миниатюры, адаптивные версии изображений и WordPress-суффиксы размеров, то базовый вариант чаще всего скачает именно уменьшенные версии.

Почему понадобился второй скрипт

После запуска первого скрипта стало видно, что он работает, но не решает задачу полностью. Изображения выгружались, но часто были маленькими. А нужны были именно большие файлы.

Это особенно характерно для WordPress-сайтов: одна и та же картинка может существовать в нескольких вариантах, например:

  • dsc-0027-300x200.jpg — миниатюра;
  • dsc-0027-768x512.jpg — средний размер;
  • dsc-0027.jpg — исходный файл.

Если просто забирать src, можно получить не оригинал, а только одну из автоматически сгенерированных копий. Именно поэтому пришлось дорабатывать решение.

Скрипт №2: выгрузка изображений в максимальном размере

Во втором варианте логика стала умнее: скрипт не просто скачивает то, что видит, а пытается добраться до максимально крупных версий файлов.

Что изменилось:

  • из URL удаляются суффиксы размеров вроде -300x200;
  • проверяются дополнительные атрибуты: data-src, data-large, data-full-url;
  • при наличии srcset можно взять самую крупную версию;
  • дубликаты пропускаются;
  • в логах видно, что именно было скачано.

Код скрипта:

import os
import re
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, unquote


def get_largest_image_url(img_url):
    """Удаляет суффиксы размеров вроде -300x200 перед расширением файла."""
    return re.sub(r'-\d+x\d+(?=\.\w+$)', '', img_url)


def get_image_candidate(img, page_url):
    img_url = (
        img.get('src') or
        img.get('data-src') or
        img.get('data-large') or
        img.get('data-full-url')
    )

    if img.get('srcset'):
        srcset = [item.strip() for item in img['srcset'].split(',') if item.strip()]
        if srcset:
            last_item = srcset[-1].split()[0]
            img_url = last_item

    if not img_url:
        return None

    return urljoin(page_url, unquote(img_url))


def download_images(url, save_folder='images'):
    if not os.path.exists(save_folder):
        os.makedirs(save_folder)

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36'
    }

    response = requests.get(url, headers=headers)
    response.raise_for_status()

    soup = BeautifulSoup(response.text, 'html.parser')
    img_tags = soup.find_all('img')

    print(f'Найдено изображений: {len(img_tags)}')

    downloaded_urls = set()

    for i, img in enumerate(img_tags, 1):
        img_url = get_image_candidate(img, url)
        if not img_url:
            continue

        largest_url = get_largest_image_url(img_url)

        if largest_url in downloaded_urls:
            print(f'[{i}] Пропущено (дубликат): {largest_url}')
            continue

        filename = os.path.basename(largest_url.split('?')[0]) or f'image_{i}.jpg'
        filepath = os.path.join(save_folder, filename)

        try:
            img_data = requests.get(largest_url, headers=headers, stream=True)
            img_data.raise_for_status()

            with open(filepath, 'wb') as f:
                for chunk in img_data.iter_content(1024):
                    f.write(chunk)

            downloaded_urls.add(largest_url)
            print(f'[{i}] Сохранено: {filename} ({os.path.getsize(filepath) // 1024} KB)')
        except Exception as e:
            print(f'[{i}] Ошибка загрузки {largest_url}: {e}')


if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(description='Скачивает изображения в максимальном разрешении')
    parser.add_argument('url', help='URL страницы для парсинга изображений')
    parser.add_argument('--folder', default='images', help='Папка для сохранения (по умолчанию: images)')
    args = parser.parse_args()

    print(f'Загрузка изображений с: {args.url}')
    print(f'Папка для сохранения: {args.folder}')

    download_images(args.url, args.folder)

Как запустить:

python largest_image_downloader.py "https://example.com/product/" --folder "high_res"

Когда использовать именно его:

  • если сайт на WordPress и создаёт несколько размеров одного изображения;
  • если нужны исходники, а не миниатюры;
  • если на странице используются srcset и lazy load;
  • если нужно получить более качественный результат без ручной переборки ссылок.

Пример практического применения

Представим типичную ситуацию: на странице проекта вы видите фотографию дома. В HTML может подставляться уменьшенная версия, например dsc-0027-300x200.jpg. Но в каталоге загрузок реально существует полноразмерный файл dsc-0027.jpg.

Базовый скрипт, скорее всего, скачает первую версию. А доработанный попробует убрать суффикс размера и получить уже оригинал. Именно в этом и состоит практическая ценность второго варианта.

Возможные проблемы и что с ними делать

1. Сайт блокирует запросы

Попробуйте добавить больше заголовков в headers, например Referer. Иногда сервер просто осторожно относится к автоматическим запросам.

2. Скрипт не видит изображения

Возможно, они загружаются через JavaScript. В этом случае BeautifulSoup не поможет, потому что он видит только исходный HTML. Тогда уже стоит использовать selenium.

3. Ошибка SSL-сертификата

Технически можно добавить verify=False в requests.get(), но это небезопасно, поэтому использовать такой приём стоит только осознанно.

4. Всё равно скачиваются маленькие изображения

Тогда нужно смотреть, как именно сайт хранит или подставляет оригиналы. Иногда они лежат не в очевидном месте, иногда полный URL находится в data-атрибутах, а иногда сайт вообще отдаёт изображения через JavaScript-галерею.

Что важно с практической точки зрения

Мне особенно нравится, что здесь Python выступает не как «ещё одна абстрактная тема для изучения», а как реальный прикладной помощник.

  • Есть задача — выгрузить изображения.
  • Есть минимальное решение — базовый скрипт.
  • Есть обратная связь от практики — скачались миниатюры.
  • Есть развитие — доработка скрипта под реальные условия сайта.

И это очень хороший формат обучения: не просто читать теорию, а решать живую задачу, видеть ограничения и на их основе улучшать код.

Что в итоге

Если вам нужно быстро собрать все изображения со страницы, можно начать с самого простого варианта. Если же нужны именно максимально крупные версии файлов, лучше сразу использовать второй скрипт.

Именно за такие прикладные сценарии я всё больше люблю Python: немного кода, немного логики — и то, что вручную заняло бы часы, превращается в понятный и управляемый процесс.

Если коротко: когда понадобилось выгрузить все картинки с сайта в максимально возможном размере, оказалось, что это можно решить не десятками ручных действий, а двумя понятными скриптами и несколькими командами в терминале.