Создание полноразмерных скриншотов web-ресурсов

Довольно полезным сервисом является создание полноразмерных скриншотов web-ресурсов.
Реализуем этот сервис буквально за 5 минут.

Задачи:


1) Создание полноразмерных скриншотов сайтов (полный скриншот по длине и ширине, а не захват окна браузера)
2) веб-интерфейс

Технологии:


— ОС — Ubuntu 10.04
— xvfb — Виртуальный фреймбуффер (Fake Xserver)
— CutyCapt — кроссплатформенная утилита для рендеринга web-страниц
— php — для веб-интерфейса


Реализация:



— Установка ПО


1. Установка xvfb

aptitude install xvfb

2. Установка CutyCapt


2.1 Сперва устанавливаем Subversion.

aptitude install subversion libqt4-webkit libqt4-dev g++

2.2 После установки SVN создаем директорию для CutyCapt и скачиваем исходники:

mkdir /usr/ccapt
cd /usr/ccapt
svn co cutycapt.svn.sourceforge.net/svnroot/cutycapt

Далее приступим к сборке:

cd cutycapt/CutyCapt
qmake
make

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

xvfb-run --server-args="-screen 0, 1024x768x24" /usr/ccapt/cutycapt/CutyCapt/CutyCapt --url=http://habrahabr.ru --out=/var/www/images/habrahabr_ru.jpg

— Веб-интерфейс


3.1 Напишем простой php-скрипт для создания скриншотов


<?
// Директория для изображений
$path = '/var/www/images/';

// URL директории с изображениями на нашем сайте
$web = 'http://kih.kz/images/';


function screenshot($source,$filename)
{
	system('xvfb-run --server-args="-screen 0, 1024x768x24" /usr/ccapt/cutycapt/CutyCapt/CutyCapt --url=http://'.$source.' --out=/var/www/images/'.$filename);
	
}


if(!isset($_POST['url']))
{
	print '<html>'.
	'<head>'.
	'<title>Полноразмерный скриншот сайта</title>'.
	'</head>'.
	'<body>';

	print '<form action="" method="post">'.
	'URL:<br />'.
	'<input name="url" type="text" value="http://">'.
	'<input type="submit" value="Send">'.
	'</form>';

	print '</body>'.
	'</html>';
}
else
{
	// Будем делать скриншот главной страницы сайта. Берем из url только host
	$site = parse_url($_POST['url']); 
	
	// Заменяем точку в доменном имени на знак нижнего подчеркивания
	$filename = str_ireplace('.','_',$site["host"]).'.jpg';

	// Проверяем существование файла скриншота
	if(file_exists($path.$filename))
	{   
		// Если скриншоту меньше суток - новый не делаем
		if (system('find '.$path.' -type f -name '.$filename.' -mtime -1')) 
		{
			print 'Извините, скриншот данного сайта уже существует и сделан в посление сутки!<br />';
			print '<a href="'.$web.$filename.'">'.$web.$filename.'</a>';
		}
		else
		{
			screenshot($site["host"],$filename);
			print '<a href="'.$web.$filename.'">'.$web.$filename.'</a>';

		}
	}
	else
	{
		screenshot($site["host"],$filename);
		print '<a href="'.$web.$filename.'">'.$web.$filename.'</a>';
	}
}

?>


Вывод:


Вот таким, довольно легким способом мы получили удобный скриншотер сайтов, который отлично делает скриншоты сайтов с Flash, и создает скриншот в полный размер, а не обрезает его по размеру окна браузера.

Пример:


Все действия проделанные в данной заметке реализованы тут.
Временно недоступен.

Спасибо за внимание.

UPD:
Само по себе создание скриншота довольно ресурсоемкое и требуются значительные временные затраты на создание скриншота. (естественно, зависит и от канала запрашиваемого сайта).
Данный пример расположен на слабеньком VDS, и может не выдержать нагрузки.
Посему, прошу не сетовать, если пример будет недоступен.

UPD2:
Мой слабенький VDS, к сожалению, не осиливает такой нагрузки, поэтому, вернее всего пример будет недоступен.
Поделиться публикацией
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
Комментарии 41
  • 0
    В примере, при переходе по ссылке на созданный скрин, выползает 404.
    • 0
      напишите, пожалуйста URL, скриншот которого Вы хотели сделать.
      • 0
        efir.biz
        kandagar.com

        Два попробовал.
        • +2
          Прошу прощения. Мой слабенький VDS не выдержал хабр-эффекта! =)

          Как только восстановлю — обновлю пост.
          • 0
            А теперь сразу по ссылке отображается «No input file specified.» :)
    • +1
      Костылястый такой костыль… PhantomJS не канает? ( habrahabr.ru/blogs/javascript/116789/ )
      • 0
        Я описал один из вариантов.

        Про PhantomJS почитаю подробнее позднее.

        З.Ы. я не уверен, но есть подозрение, что PhantomJS будет некорректно работать с flash на сайтах.
        • 0
          Судя по документации ( code.google.com/p/phantomjs/wiki/Interface ) он и Flash прекрасно подхватит с правильным ключиком запуска. А так мы избавимся от лишнего «жруна» — Xvfb. Тем более на каждый скрин поднимать заново Xvfb, это же жесть какая жесть…
          • +2
            Ну как бы все равно придется использовать Xvfb
            Иначе Фантом вам скажет: [WARNING] phantomjs: cannot connect to X server
            (мы же говорим о скрининге с консоли на сервачке, да?)
            • +1
              Кхм, действительно. Однако, в любом случае по-моему лучше не мучать Xvfb-run на каждый запуск а запустить один инстанс Xvfb ( Xvfb :0 -screen 0 640x480x24 & ) и уже в нём запускать любую из утилиток ( DISPLAY=:0 myLovelyUtility )

              Почему то думал, что PhantomJS умеет таки без Иксов рендерить, сорри
      • 0
        Пример временно недоступен. Я убрал скрипт, пока восстановлю серверную часть.

        P.S. пример по ссылке — это пока не полноценно работающий сервис, это лишь пример реализации действий, указанных в статье.
        • +4
          Я когда-то писал фактически аналогичную статью. )
          • 0
            Действительно, реализация схожая.

            Спасибо за комментарий.
          • 0
            Проверил из консоли: работает! Правда хотелось бы побыстрее… Получается от 5 до 30 сек в зависимости от УРЛа.
            • 0
              Есть адреса, загрузки которых оно не дожидается совсем. Применяю CutyCapt в продакшене, пришлось сделать специальный скрипт–прибиватор для отдельных случаев «вечной загрузки».
              • 0
                Основная причина в длительном создании скриншота — доступность сайта, который скриншотится.
                Это ведь равносильно тому, что мы запросим сайт через браузер.

                Подумаю над решением проблемы.

                Спасибо за комментарий.
              • 0
                А как у него со шрифтами? Экспериментировал со скриншотерами, но шрифты так и не удалось добить.
                • 0
                  У меня в профиле есть линк сайта si**t.in (не рекламлю,), на котором все скриншоты (на страницах, где описаны конкретные сайтики) сделаны через Кутикапт. Вот можете по ним и судить.
                  • 0
                    Спасибо. Посмотрел — тоже самое что было и у меня. Шрифты похожи, но при внимательном рассмотрении видно, что не те :(. Смотрю под виндой.
                  • 0
                    Я заметил проблему с шрифтами только на китайском сайте-аукционе.

                    Спасибо за комментарий.
                    • 0
                      Мне не удалось добиться полного сходства с тем, что я вижу у себя в firefox или в хроме. Все равно есть отличия. Использовал я, правда, решение с запуском firefox в xvfb. Потому и интересно, на сколько точным получается совпадение скриншотов с виндой.
                  • 0
                    Можно написать приложение на python с использование qt-webkit будет более гибкое решение. В свое время перепробывал для pr-cy.ru много готовых решений, ниодно не устроило.
                    • 0
                      CutyCapt использует qt-webkit, решение на C++ в некоторых случаях более стабильно, чем на python, но оба из них, конечно, имею право на жизнь :)
                    • 0
                      Ещё у вас не на всех сайтах flash работает.
                      • +1
                        У меня есть свой маленький проектик, типа «домашняя страничка» с любимыми ссылками.

                        Когда переделывал его в очередной раз — сделал автоснятие скриншотов с помощью wkhtml.

                        Главное достоинство — рендер страниц посредством webkit. Flash так и не смог завести, хотя, говорят, это возможно.

                        Посмотреть в работе можно тут, если будет интересно — расскажу как прикручивать wkhtml себе на сайт.

                      • 0
                        Мечтаю о приложинии, которое бы умело не только создавать полноразмерные скриншоты сайтов, но и готовить их к печати. А именно: увеличивать изображения без потери качества и без каких либо алгоритмов, просто увеличивая размеры пикселей в 2,3,4 и так далее раз.

                        Сейчас это приходится делать в фотошопе, принскриня увеличенное изображение. Неудобно.
                        • +1
                          А зачем принтскринить увеличенное изображение и вставлять в фотошоп? Можно же в нем прямо и увеличить :)
                          • 0
                            Если из маленького изображения сделать большое, то оно сильно потеряет в качестве.
                            • +1
                              > без потери качества и без каких либо алгоритмов
                              В фотошопе это делается так:
                              1. Image > Image Size…
                              2. Выбираем нужный размер и dpi принтера, режим интерполяции Nearest Neighbor

                              i55.tinypic.com/316sv9e.png
                              • 0
                                Круть! Спасибо .)
                                • 0
                                  Не за что :) Можно, в принципе, написать такое расширение для Хрома. Если что, скину в личку.
                                  • 0
                                    Да статью на Хабре на тему сделайте, интересно же.
                          • 0
                            Скриншот страницы в компоненте WebBrowser www.delphiexpert.ru/view_lesson.php?id=58
                            сохраняет скриншот окна
                            можно дописать перемещение невидимое окна чтоб охватить все зоны и сохранить в 1 файл
                            я уже доработал чтоб JPEG был прогрессивный и можно устанавливать качество его
                            можно сохранять в тот же PNG, затем фрактально к примеру увеличивать и сохранять в нужном формате

                            ТИГРА, автор tigrazone.narod.ru/AISPLIT.ZIP
                          • 0
                            Скриншот страницы в компоненте WebBrowser www.delphiexpert.ru/view_lesson.php?id=58
                            • 0
                              В Ubuntu 11.04 CutyCapt можно и не собирать из исходников, он уже доступен из стандартного репозитория.
                              sudo apt-get install xvfb cutycapt
                              xvfb-run --server-args="-screen 0, 1024x768x24" cutycapt --url=http://habrahabr.ru --out=habrahabr_ru.jpg
                              • 0
                                Что-то задавался такой же проблемой и решил вам рассказать озамечтельной системе тестирования Selenium. В ней есть модули для создания скриншотов страниц, а поддержка языков позволяет написать небольшой Database Queue Thread, который будет опрашивать базу и делать скриншоты и складывать их куда Вы пожелаете.

                                P.S. Помоему гораздо более простой вариант чем городить различные фреймбуферные декстопы… Опять же это всего лишь вариант если уж действительно так надо скриншоты делать…
                                • 0
                                  Скажите, а с помощью screen и xvfb можно сделать «висящее в фоне» GUI приложение?
                                  • 0
                                    А чем отличается полный скриншот по длине и ширине от захвата окна браузера?
                                    • 0
                                      А вы пробовали решить проблему для страничек/сайтов, где требуется авторизация?

                                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.