/ php

Как сделать скриншот сайта по URL на PHP

В этой статье я покажу вам, как можно средствами PHP создать скриншот любой веб-страницы. Для решения этой задачи существует множество различных сервисов, предоставляющих API для создания скриншотов. В этой статье я буду использовать Google API, позволяющее запросто сделать скриншот по указанному URL-адресу. Преимуществом использования Google API в том, что для его использования не потребуется регистрация, или дополнительная настройка чего-либо. Скрипт, который мы напишем по ходу этой статьи можно будет скопировать и использовать, без дополнительных настроек и переписывания кода.

Disclaimer

Прежде всего, отвечу на вопрос: зачем использовать API стороннего сервиса? Можно ли обойтись исключительно своими силами своим сервером, и языком PHP. Отвечу без промедлений - нет. Почему? Потому что для создания скриншота в том виде, в каком он отображается у вас в браузере, как раз таки и требует запуска самого браузер. А ввиду того, что PHP не имеет встроенного браузера, или средств для его реализации, то и рендеринг страницы сделать на нём невозможно.
В следующих статьях по этой теме, я покажу ещё примеры того, как можно делать скрины из PHP другим способом. Но пока что, поверьте на слово, использование стороннего сервиса - это самое простое решение.

Всё что нам нужно - это вызвать API Google Page Speed сервиса. Url по которому мы будет обращаться к API - https://www.googleapis.com/pagespeedonline/v2/runPagespeed?screenshot=true&strategy=mobile&url={SOMEURL}
где {SOME_URL} - это URL-адрес страницы, которую нужно заскринить

Рассматривая подробнее Google API PageSpeed URL, можно увидеть, что здесь есть 3 основных параметра:

  • screenshot=true - что сообщает сервису о том, что нужно создать скриншот страницы, и является обязательным параметром для создания скриншота
  • strategy=mobile - опциональный параметр, которые говорит о том, что нужно сделать скриншот с мобильного телефона. Если нужно десктопная версия, то этот параметр удаляется.
  • url=... - обязательный параметр URL-адрес страницы, которую нужно заскринить.

Запрос к API

Когда вы отправить GET-запрос по этому URL-адресу, вы получите ответ примерно такого вида: response

Я сделал скрин на примере моего блога, потому полный URL-адрес выглядит так: https://www.googleapis.com/pagespeedonline/v2/runPagespeed?screenshot=true&strategy=mobile&url=https://badcode.ru

Изучив подробнее, можно заметить, что есть поле screenshot, которое содержит массив с параметрами изображения: mime_type, data, width, height.

Полезная для нас информация, как раз-таки находится под ключом data. Здесь содержится изображение закодировано в base64, но с некоторыми отличиями, которые мы сейчас исправим.

Для преобразования google-формата картинки к обычному, читаемому base64, нужно преобразовать следующие символы:

  • _ заменить на /
  • -, пробелы заменить на +
  • а так же, нужно вырезать строку data:image/jpeg;base64,

Ограничения

Это API не является идеальным решением для создания скриншотов. Но, на случай войны, если нужно быстрое, рабочее решение, без установки дополнительного ПО - годится.

  • Картинки получаются небольшого разрешения 320px, что не подходит для создания скришотов высокого разрешения.
  • Невозможно создать скрины страниц, требующих аутентификации.
  • Не всегда скрины получаются в соответствии с оригинальной разметкой сайта, особенно, в случае SPA.
  • Медленно :(

Полный пример

В этом примере я объединил все замечания, рассмотренные в этой статье, и создал функцию, которая сохраняет скриншот URL-страницы на компьютер.

function makeScreen($url, $save_to, $mobile = true) {
    $query = http_build_query(array_filter([
        'strategy'      => $mobile ? 'mobile' : null,
        'screenshot'    => 'true',
        'url'           => $url
    ]));
    $api_url = "https://www.googleapis.com/pagespeedonline/v2/runPagespeed?{$query}";
    // делаем запрос к API
    $result = json_decode(file_get_contents($api_url), true);

    // преобразование к обычному base64 формату
    $screen_data = str_replace(
        ['_', '-', ' ', 'data:image/jpeg;base64,'],
        ['/', '+', '+', ''],
        $result['screenshot']['data']
    );

    // сохраняем изображение
    return file_put_contents($save_to, base64_decode($screen_data));
}

// мобильная версия
$content = makeScreen('https://badcode.ru', __DIR__ . '/badcode.jpg');
// ПК версия
$content = makeScreen('https://badcode.ru', __DIR__ . '/badcode_PC.jpg', false);

Теперь, для создания скриншота просто вызовите функцию makeScreen($url, $saveImageTo, $isMobileVersion = true),
где $url - это URL-адрес страницы, скрин которой нужно создать,
$saveImageTo - путь, по которому изображение будет сохранено. В примере я прописал DIR . '/badcode.jpg', что сохранило картинку badcode.jpg в текущей директории,
$isMobileVersion - необязательный параметр, который принимает значения true|false. Если значение не было передано, то создаётся мобильная версия.

Вот так, оказывается, просто написать php скрипт создания скриншотов сайтов. Теперь вы можете делать скриншот страницы на php в любом своём приложении.