Вашему внимания предлагаются 4 linux библиотеки создания скриншотов (Webscreenie, PhantomJs, PythonWebkit2Png и WkHtml), которые могут сделать запрос к сайту, получить ответ, отрендерить ответ, создать снимок сайта (скриншот, снапшот, в англоязычной литературе - screenshot). Либы позволяют использовать возможности WebKit в консоли.
Библиотеки создания скриншотов полностью работоспособны под Debian7, также я не заметил никаких проблем в установке и работе под Ubuntu.
1. Webscreenie
Установка Webscreenie:
The project url is: https://webscreenie.googlecode.com/svn/trunk
Команда запуска webscreenie:
/usr/bin/xvfb-run -f /tmp/Xauth -a /usr/bin/webscreenie --delay 1000 --size 1000x1000 --url 'http://jeka.by/' --file /tmp/snap/jeka.by/Webscreenie.png
2. PhantomJs
Установка PhantomJs (use precompiled binary):
cd /opt wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.7-linux-x86_64.tar.bz2 tar xjf phantomjs-1.9.7-linux-x86_64.tar.bz2 mv phantomjs-1.9.7-linux-x86_64 phantomjs rm phantomjs-1.9.7-linux-x86_64.tar.bz2 // На основе examples/rasterize.js делаем свой snapshot-phantom.js
phantom-snapshot.js:
var page = require('webpage').create(), system = require('system'), address, output, size; if (system.args.length < 3 || system.args.length > 4) { console.log('Usage: phantom-snapshot.js URL filename [width*height]'); phantom.exit(1); } else { address = system.args[1]; output = system.args[2]; page.viewportSize = { width: 600, height: 600 }; page.clipRect = { top: 0, left: 0, width: 600, height: 600 }; if (system.args.length > 3) { size = system.args[3].split('x'); page.viewportSize = { width: size[0], height: size[1] }; page.clipRect = { top: 0, left: 0, width: size[0], height: size[1] }; } page.open(address, function (status) { if (status !== 'success') { console.log('Unable to load the address!'); phantom.exit(); } else { window.setTimeout(function () { page.render(output, {format: 'png', quality: '80'}); phantom.exit(); }, 200); } }); }
Команда запуска PhantomJs:
/opt/phantomjs/bin/phantomjs /pathto/phantom-snapshot.js http://jeka.by/ /tmp/snap/jeka.by/PhantomJs.png 1000x1000
Python-webkit2png
Установка python-webkit2png:
apt-get install python-qt4 libqt4-webkit xvfb python-setuptools cd /opt git clone https://github.com/adamn/python-webkit2png.git python-webkit2png cd python-webkit2png python setup.py install
Команда запуска pythonWebkit:
webkit2png -x 1000 1000 --geometry=1000 1000 --output=/tmp/snap/jeka.by/PythonWebkit.png --timeout=180 http://jeka.by/
WkHtml
Установка WkHtml:
cd /opt wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1-dev/wkhtmltox-0.12.1-c22928d_linux-wheezy-amd64.tar.xz tar -xpJf wkhtmltox-0.12.1-c22928d_linux-wheezy-amd64.tar.xz rm wkhtmltox-0.12.1-c22928d_linux-wheezy-amd64.tar.xz
Команда запуска WkHtmlToPng:
/opt/wkhtmltox-0.12.1-c22928d/bin/wkhtmltoimage --width 1000 --height 1000 --crop-w 1000 --crop-h 1000 --format png --quality 80 http://jeka.by/ /tmp/snap/jeka.by/WkHtml.png
Создать скриншот сайта на php
Ниже представлены php классы, которые создают и сохраняют скриншоты страницы. Для работоспособности нужно установить хотя бы одну из библиотек снапшотов. Все 4 библиотеки можно поставить одновременно на одну машину, никаких конфликтов в пакетах не возникает.
<?php /*from config: 'snapshots' => array( 'width' => 1000, 'height' => 1000, );*/ class Snapshot_Parser_Webscreenie extends Snapshot_Parser_Abstract { /** * @param string $requestedUrl * @param string $snapshotPath */ public function createSnapshot($requestedUrl, $snapshotPath) { $snapshotConfig = Core_Config::getValue('snapshots'); $command = $snapshotConfig['commandPath'] . ' --delay 1000 ' . ' --size ' . $snapshotConfig['width'] . 'x' . $snapshotConfig['height'] . ' --url ' . escapeshellarg($requestedUrl) . ' --file ' . $snapshotPath; $this->getLog()->write('Executing command: ' . $command); $this->execute($command); } } class Snapshot_Parser_PhantomJs extends Snapshot_Parser_Abstract { /** * @param string $requestedUrl * @param string $snapshotPath * @throws Parser_Exception_OperationFailed */ public function createSnapshot($requestedUrl, $snapshotPath) { $phantomPath = "/opt/phantomjs/bin/phantomjs"; $snapshotJsFilePath = PROJECT_BIN_DIR . '/phantom-snapshot.js'; if (!file_exists($phantomPath)) { throw new Parser_Exception_OperationFailed("Can not found PHANTOM JS by path $phantomPath. Install it or set correct path to library."); } $snapshotConfig = Core_Config::getValue('snapshots'); $cmd = "$phantomPath $snapshotJsFilePath $requestedUrl $snapshotPath {$snapshotConfig['width']}x{$snapshotConfig['height']}"; $this->getLog()->write('Executing command: ' . $cmd); $this->execute($cmd); } } class Snapshot_Parser_PythonWebkit extends Snapshot_Parser_Abstract { /** * @param $requestedUrl * @param $snapshotPath * @throws Parser_Exception_OperationFailed */ public function createSnapshot($requestedUrl, $snapshotPath) { $webkit2PngPath = "/opt/python-webkit2png/scripts/webkit2png"; if (!file_exists($webkit2PngPath)) { throw new Parser_Exception_OperationFailed("Can not found webkit2png by path $webkit2PngPath. Install it or set correct path to library."); } $snapshotConfig = Core_Config::getValue('snapshots'); $cmd = "python $webkit2PngPath" . " -x {$snapshotConfig['width']} {$snapshotConfig['height']}" . " --geometry={$snapshotConfig['width']} {$snapshotConfig['height']}" . " --output=$snapshotPath" . " --timeout=" . Wi_Snapshot_Parser_Abstract::PROCESS_TIMEOUT . " $requestedUrl"; $this->getLog()->write('Executing command: ' . $cmd); $this->execute($cmd); } } class Snapshot_Parser_WkHtml extends Snapshot_Parser_Abstract { /** * @param string $requestedUrl * @param string $snapshotPath * @throws Parser_Exception_OperationFailed */ public function createSnapshot($requestedUrl, $snapshotPath) { $libPath = "/opt/wkhtmltox-0.12.1-c22928d/bin/wkhtmltoimage"; if (!file_exists($libPath)) { throw new Parser_Exception_OperationFailed("Can not found wkhtmltoimage by path $libPath. Install it or set correct path to library."); } $snapshotConfig = Core_Config::getValue('snapshots'); $cmd = $libPath . " --width {$snapshotConfig['width']} --height {$snapshotConfig['height']}" . " --crop-w {$snapshotConfig['width']} --crop-h {$snapshotConfig['height']}" . " --format png" . " --quality 80" . " $requestedUrl $snapshotPath"; $this->getLog()->write('Executing command: ' . $cmd); $this->execute($cmd); } }
Под спойлером скриншот сайта jeka.by 1000x1000px, сделанный с помощью webscreenie. Кликните по картинке для открытия в полный размер.

Какая же библиотека создания снапшотов лучше?
На этот вопрос нельзя ответить однозначно. Я проводил испытания, создавая снапшоты главных страниц сайтов, отвечающих с кодом 200. Webscrenie показал наиболее хорошие результаты в количестве успешных скриншотов. В то же время webscreenie наиболее медленная библиотека. Хотя в целом по скорости работы и по качеству все 4 либы практически одинаковы. Для Webscreenie качество снапшотов нельзя задать, как видно по коду, можно задать качество для PhantomJs и WkHtml. Для WkHtml качество нужно задавать обязательно (около 80 из 100), иначе размер снапшотов WkHtml значительно превышает все остальне библиотеки и составляет порядка 1-4Мб(!) для снапшота 1000x1000px, что слишком много.
Сравнительные результаты теста на виртуальной машине debian7 (выделено одно ядро, 1024Мб ОЗУ) в десять потоков библиотек Webscreenie, PhantomJs, WkHtml, PythonWebkit приведены в таблицах:
всего доменов | 3382 | % успешности |
Успешных Webscreenie | 3176 | 93,9% |
Успешных PhantomJs | 3016 | 89% |
Успешных WkHtml | 3055 | 90,3% |
Успешных PythonWebkit | 3038 | 89,8% |
Библиотека | Время, мс | Размер, кб |
---|---|---|
Webscreenie | 9914.76 | 398.94 |
PhantomJs | 8533.03 | 510.06 |
WkHtml | 7627.38 | 489.80 |
PythonWebkit | 7936.42 | 376.79 |