Пользователь
0,0
рейтинг
13 сентября 2011 в 14:19

Разработка → Создание полноразмерных скриншотов 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, к сожалению, не осиливает такой нагрузки, поэтому, вернее всего пример будет недоступен.
@Twost
карма
11,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (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 себе на сайт.

    • +1
      Ссылки не вставились.

      Сайт wkhtmltopdf — code.google.com/p/wkhtmltopdf/
      Мой сайтик, где можно глянуть пример работы — webstartpage.ru

      P.S.
      С некоторых пор не могу пользоваться тегами — никак не привыкну.
    • +1
  • 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
    А вы пробовали решить проблему для страничек/сайтов, где требуется авторизация?

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