Сегодня я работаю над решением для создания скриншотов веб-сайтов для одного из моих проектов. Изучив различные темы в сети, я пришел к выводу, что использование PhantomJS, вероятно, было моим лучшим выбором.
Так как я работал на локальном сервере vagrant (Homestead), мне потребовался пакет от jonnyw/php-phantomjs
(https://packagist.org/packages/jonnyw/php-phantomjs) в существующий проект и запускается с помощью основного сценария:
$client = Client::getInstance();
$client->debug(true);
$client->setBinDir('/home/admin/domains/domain.com/public_html/bin/');
$request = $client->getMessageFactory()->createCaptureRequest('http://www.domain.com/preview/H/31', 'GET');
$request->setCaptureFile('/home/admin/domains/domain.com/public_html/screens/sample.jpg');
$request->setViewportSize(1366, 768);
$response = $client->getMessageFactory()->createResponse();
$client->send($request, $response);
Мне потребовалось некоторое время, прежде чем код перестал выдавать предупреждения, но в конце концов код работал так, как должен! Затем я переместил код в проект, в котором он должен был находиться, что написано в процедурном php-коде. Мне потребовался пакет, включающий автозагрузчик и выполняющий точно такую же команду, что и в моей среде Vagrant.
Результат был немного другим: заголовок не показывался, а фоновое изображение тоже не показывалось. Возможно, мне нужно добавить, что к заголовку прикреплен собственный шрифт.
Несколько недель назад я настроил сервер для клиента, который требовал Laravel, я также потребовал пакет на этом сервере и выполнил тот же код. Сначала я получал несколько случайных белых страниц, но в итоге я получил ожидаемый скриншот. Я могу жить с тем фактом, что что-то на скриншоте получается белым, если они в конечном итоге подойдут правильно.
Затем я вернулся к коду, для которого предназначен этот скрипт, и сделал еще несколько снимков. Но результаты оставались белыми или отсутствовали некоторые элементы (заголовок пользовательского шрифта + фоновое изображение). Моя последняя попытка была изменить capture.proc
файл, я добавил функцию setTimeout перед рендерингом изображения. Это решило одну проблему: у меня не было белых изображений с тех пор, но я не решил самую важную проблему: отсутствующий заголовок и фон.
Я дважды проверил все файлы bin, все они используют версию 1.9.7 PhantomJS, поэтому я сомневаюсь, что там есть проблема. Но может ли быть разница в конфигурации сервера (или версии PHP), которая не дает сценарию дать правильный результат?
Просто для того, чтобы предоставить как можно больше информации, проблемный сервер имеет самую низкую версию PHP:
Похоже, вам нужно немного подождать после загрузки страницы и перед тем, как сделать снимок экрана. Одностраничные приложения и веб-шрифты обычно занимают немного времени для загрузки и рендеринга, тогда как PhantomJS немного стремится запустить событие завершения загрузки и сообщить о завершении загрузки.
Вы можете втиснуть в $request->setDelay(2);
между ...->createCaptureRequest(..)
а также $request->setCaptureFile(...)
, Увидеть документация.
Использование статической задержки не очень надежно. Лучше использовать waitFor()
функция который срабатывает, как только условие (например, определенный элемент страницы появляется на странице) выполняется. php-phantomjs не предоставляет такую функциональность через свой API, но вы можете напрямую использовать скрипт PhantomJS, который может делать подобные вещи. Увидеть документация.
Других решений пока нет …