T.M. SoftStudio

feci quod potui, faciant meliora potentes

Использование HTMLUnit и html2canvas для создания скриншотов сторонних веб сайтов

Инструмент html2canvas (http://html2canvas.hertzen.com/) позволяет создавать скриншоты Web страниц или их частей на основе отображаемых DOM объектов.

Однако инструмент html2canvas имеет ограничения – он не может считывать ресурсы других доменов.

Поэтому для создания скриншотов сторонних Web сайтов необходимо привлекать прокси-сервис на стороне сервера, который будет передавать HTML-код и изображения от стороннего Web-сайта стороне клиента, использующего инструмент html2canvas.

Для создания такого прокси-сервиса можно привлечь Headless-браузер HTMLUnit (http://htmlunit.sourceforge.net/), моделирующий HTML-документы и предоставляющий API для анализа HTML-страниц.

Для использования инструмента html2canvas на HTML-страницу приложения, которая будет отображать скриншот стороннего Web-сайта, добавим код:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<meta http-equiv="content-type" content="text/html; charset=UTF-8">

<title>Sitemap Screenshots</title>

</head>

<script src="js/jquery.js"></script>

<script type="text/javascript" src="js/html2canvas.js"></script>

<script type="text/javascript">

$(document).ready(function() {

var url="http://www.cnn.com/";

$.ajax({

type: "POST",

url: "/htmlunit",

data:{ wait: "2000", url: url },

async: false,

success : function(data) {

$(".screenframe").remove();

var iframe="<iframe class='screenframe' style='display:none;'></iframe>";

$('body').append($(iframe));

var target = $('iframe').contents()[0];

target.open();

target.write(data);

target.close();

$('iframe').load(function(){

var target = $(this).contents().find('body');

html2canvas(target, {

onrendered: function(canvas) {

var data = canvas.toDataURL();

$('body').append("<img width='500' src="+data+" />");

}

});

});

}

});

});

</script>

<body>

</body>

</html>

Данный скрипт передает URL-адрес стороннего Web-сайта сервлету на стороне сервера, который использует HTMLUnit для возврата обратно HTML-кода стороннего Web-сайта.

После получения HTML-кода стороннего Web-сайта скрипт создает фрейм, добавляет его на страницу и записывает в него HTML-код стороннего Web-сайта.

После загрузки фрейма инструмент html2canvas создает его изображение, которое и добавляет на страницу приложения.

Код сервлета, служащего прокси-сервисом:

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.gargoylesoftware.htmlunit.BrowserVersion;

import com.gargoylesoftware.htmlunit.WebClient;

import com.gargoylesoftware.htmlunit.html.HtmlPage;

@SuppressWarnings("serial")

public final class HTMLUnitServlet extends HttpServlet {

@Override

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

int wait = 2000;

if (request.getParameter("url") != null) {

final WebClient webClient = new WebClient(BrowserVersion.CHROME);

webClient.getOptions().setThrowExceptionOnScriptError(false);

String url = request.getParameter("url");

HtmlPage page = webClient.getPage(url);

if (request.getParameter("wait") != null) {

wait=Integer.parseInt( request.getParameter("wait") );

}

webClient.waitForBackgroundJavaScript(wait);

response.setCharacterEncoding("UTF-8");

PrintWriter out = response.getWriter();

String xml=page.asXml();

System.out.println(xml);

xml = xml.replace("<head>","<head><base href='"+url+"' />");

out.println(xml);

}}}

Не забудем объявить сервлет в web.xml:

<servlet>

<servlet-name>com.tmsoftstudio.HTMLUnitServlet</servlet-name>

<servlet-class>com.tmsoftstudio.HTMLUnitServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>com.tmsoftstudio.HTMLUnitServlet</servlet-name>

<url-pattern>/htmlunit</url-pattern>

</servlet-mapping>

К сожалению, такая схема создания скриншотов сторонних Web-сайтов имеет свои ограничения, связанные с возможностями HTMLUnit моделирования HTML-документов.