Webページのキャプチャ

SwingのJEditorPaneを使用してWebページのキャプチャ画像を生成する方法です。ご存知の通りHTMLEditorKitはHTML3.2までのサポートで、スタイルシート対応も不完全です。更に、JavaScriptには全く対応していません。

そのため、PC向けで、比較的新しいブラウザをターゲットにしたWebページに対して実行した場合、結果はひどいものになりますので注意してください。

携帯サイトのような単純なページをキャプチャするのは可能かと思います。また、サムネイルなども比較的簡単に作成できます。

ソースコード

import java.io.File;
import java.io.IOException;
import java.net.URL;

import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;

public class WebCapture {

    public static void main(String[] args) throws IOException {

        if (args.length < 2) {
            System.err.println(
                    "Usage: java " +
                    WebCapture.class.getName() +
                    " url file");
            System.exit(1);
        }

        new WebCapture().go(
            new URL(args[0]),
            new File(args[1]));
    }

    public void go(URL url, File file) throws IOException {

        JEditorPane editor = new JEditorPane();
        EditorKit ek = new HTMLEditorKit() {
            public ViewFactory getViewFactory() {
                return new HTMLEditorKit.HTMLFactory() {
                    public View create(Element element) {
                        View view = super.create(element);
                        if (view instanceof ImageView) {
                            ((ImageView)view).setLoadsSynchronously(true);
                        }
                        return view;
                    }
                };
            }
            public Document createDefaultDocument() {
                AbstractDocument document =
                    (AbstractDocument)super.createDefaultDocument();
                document.setAsynchronousLoadPriority(-1);
                return document;
            }
        };

        editor.setEditorKit(ek);
        editor.setPage(url);
        editor.setSize(editor.getPreferredSize());

        javax.imageio.ImageIO.write(
            getImage(editor),
            getFormatName(file.getName()),
            file);
    }

    private RenderedImage getImage(Component component) {

        Dimension dim = component.getSize();
        BufferedImage bi = new BufferedImage(
            dim.width, dim.height, BufferedImage.TYPE_INT_RGB);

        Graphics2D g2 = bi.createGraphics();
        component.paint(g2);
        g2.dispose();
        return bi;
    }

    private String getFormatName(String fileName) {
        int n = fileName.lastIndexOf(".");
        if (n == -1) {
            return null;
        }
        return fileName.substring(n+1);
    }
}

使用方法

1番目の引数にURLを、2番目に出力ファイル名を指定します。以下は例です。

java WebCapture http://www.google.com/ result.png

実行結果

当サイト(http://www.utilz.jp/)の実行結果です。かなりヒドイですね。