中文

About Seacat

Seacat is the best web snapshot server in the world. It's based on Firefox browser, running on Linux system. Seacat can capture not only the full web page as one picture, but also the absolute region of web page, and those elements identifed by class or id. For normal user, Seacat can take snapshot on user's favorite web pages, save them as pictures for future use. For internet sites, such as general search engine, vertical search engine, online bookmarks, online guide, map service and so on, taking snapshot on web pages by Seacat, can enrich user interface, enhance user experience, and improve search accuracy effectively. By Seacat, you can add more value on your web site, improve your internal value.

Features

  1. Run on background

    As a linux server program, Seacat runs on background. No need for X-Windows.
  2. Multithreaded with thread pool

    Running in multithreaded mode, Seacat can serve many user's snapshot request simultaneously.
  3. Various thumbnail sizes

    Default sizes are 160x120, but user can specify many other thumbnail sizes.
  4. Various image formats

    Default output image format is png, but you can specify other format, such as gif, jpg...
  5. Full page snapshot support

    Taking snapshot on full web page made easy by Seacat, just use an option ( enable-full:1 ).
  6. Capture specific region of web page

    You should provide the top left corner and image width and height, Seacat will help you to capture this region.
  7. Capture those elements identifed by class or id or xpath

    Given one or more class or id value, or given a xpath, Seacat can take snapshot on matched elements. It's very flexible and easy to use.
  8. Simpe interface

    Http like protocol, communication through socket, embedding in dynamic web applications should be very easy. The obvious sample is zhuatang.com.

Download

seacat-5.5-1.en_US.fc9.i386.rpm (For Fedora Core 9 Linux)
seacat-5.5-1.en_US.el5.i386.rpm (For RedHat EL 5/CentOS Linux)

Install prerequisite

For proper use Seacat, you must install ImageMagick at first. Make sure the file /usr/bin/convert and /usr/bin/composite exists and can execute.

Install

Install: rpm -ivh seacat*.rpm

Seacat server management

Configuration tool - seacatctl

usage: seacatctl command
where command is: 
1)  list
list current settings
2) set [port|rcj|vxsmin|vxsmax|pictureHome|captureWaitTime|waterMark|maxMatch|maxWidth|maxHeight] value
set config
3) proxy [ on <IP> <PORT> | off ]
set or clear proxy setting
4) help
print this help info
Example 1: seacatctl list
List current settings.
Example 2: seacatctl set port 4444
Set Seacat listen on 4444 port.
Example 3: seacatctl set rcj 4444-5555-6666
Set register code to 4444-5555-6666.
Example 4: seacatctl set vxsmin 5
Start 5 virtual browser when Seacat starts.
Example 5: seacatctl set pictureHome /root
Default picture storage home is /root.
Example 6: seacatctl set captureWaitTime 1500
Set wait time before capture to 1500ms.
Example 7: seacatctl set waterMark zhuatang.com
Set watermark text to zhuatang.com.
Example 8: seacatctl proxy on 192.168.28.91 8080
Set proxy : 192.168.28.91, port 8080.
Example 9: seacatctl proxy off
Clear proxy.
Example 10: seacatctl set maxMatch 2
Set maximum acceptable elements number matched on class or xpath
Example 11: seacatctl set maxWidth 1200
Set maximum acceptable width of full page. when the real width of full page exceeds maxWidth, Seacat will do nothing. No limits when maxWidth=0.
Example 12: seacatctl set maxHeight 2000
Set maximum acceptable height of full page. when the real height of full page exceeds maxHeight, Seacat will do nothing. No limits when maxHeight=0.
Note:vxsmax not used.

Command line capture tools - capture

usage: usage: capture [-h host] [-p port] [-f] [-s WWWxHHH...] [-w timeToWait] [-o imageFormat] [-P prefix] [-i ids ] [-c classes] [-x xpath] [-r rects] url1 url2 ...
Options:
 -h host : seacat host, default: localhost
 -p port : seacat port, default: 5060
 -f : enable full page capture
 -s WWWxHHH... : one or more thumbnail size list, WWW is thumbnail width, HHH is thumbnail height
 -w timeToWait : wait time before capture, time unit: millisecond
 -o imageFormat : default value: png
 -P prefix : prefix of picture
 -i ids : ids is one or more element id in page
 -c classes : classes is one or more element class name in page
 -x xpath : xpath is one xpath expression which target element must match
 -r rects: one or more rectangle to capture, default is "0 0 1024 768", meas x=0,y=0,width=1024,height=768
url1 url2 ... are URLs you want to take snapshot on.
Output:
<url> {+++|---} <scid>

+++ capture OK
--- capture failed
<scid> is prefix of snapshot filename. you can use "ls <scid>*" listing image files created for the <url>. Snapshot file (thumbnail) full name format: <scid>-WWWxHHH.png, where WWW is image width, HHH is image height. When full pagesnapshot enabled, <scid>-full.png snapshot file will be generated.
Example1: capture http://www.zhuatang.com
Example2: capture -s "109x82 330x220" http://www.zhuatang.com
Example3: capture -f -s "82x78 400x300" http://www.zhuatang.com http://www.zaobao.com

Register

Seacat is a shareware, free trial time is 30 days. For your proper use, please register it on time.
Contact with zhsoft88@gmail.com (Email/MSN). Price: RMB12000.00.

Seacat Protocol

Articles: How to capture specific region on page by Seacat

Example codes

Seacat.java Download

package com.zhsoft88.commons;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FilenameFilter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Arrays;

import org.apache.commons.lang.math.NumberUtils;

/**
 * seacat capture
 * @author zhsoft88
 * @since 2008-4-13
 * @update 2008-12-13
 */
public class Seacat {

	public static final int PORT = 5060;
	
	/**
	 * capture result
	 * @author zhsoft88
	 * @since 2008-4-13
	 */
	public static class SeacatResult {
		private int statusCode;
		private String statusText;
		private String scid;
		private String geometry;
		private long elaspedTime;
		private String prefix;
		private String pictureHome;
		private String[] suffixList;

		public SeacatResult() {
			// TODO Auto-generated constructor stub
		}

		public int getStatusCode() {
			return statusCode;
		}

		public String getStatusText() {
			return statusText;
		}

		public String getScid() {
			return scid;
		}

		public String getGeometry() {
			return geometry;
		}

		public long getElaspedTime() {
			return elaspedTime;
		}

		public String getPrefix() {
			return prefix;
		}

		public String getPictureHome() {
			return pictureHome;
		}

		public String[] getSuffixList() {
			return suffixList;
		}

		protected void setStatusCode(int statusCode) {
			this.statusCode = statusCode;
		}

		protected void setStatusText(String statusText) {
			this.statusText = statusText;
		}

		protected void setScid(String scid) {
			this.scid = scid;
		}

		protected void setGeometry(String geometry) {
			this.geometry = geometry;
		}

		protected void setElaspedTime(long elaspedTime) {
			this.elaspedTime = elaspedTime;
		}

		protected void setPrefix(String prefix) {
			this.prefix = prefix;
		}

		protected void setPictureHome(String pictureHome) {
			this.pictureHome = pictureHome;
		}

		protected void setSuffixList(String[] suffixList) {
			this.suffixList = suffixList;
		}

		public void dump() {
			System.out.println("SeacatResult:");
			System.out.println("statusCode="+statusCode);
			System.out.println("statusText="+statusText);
			System.out.println("scid="+scid);
			System.out.println("geometry="+geometry);
			System.out.println("prefix="+prefix);
			System.out.println("suffixList length="+suffixList.length);
			for (int i=0;i<suffixList.length;i++) {
				System.out.println("suffixList["+i+"]="+suffixList[i]);
			}
		}
	}
	
	/**
	 * capture configuration
	 * @author zhsoft88
	 * @since 2008-4-13
	 * @update 2008-12-13
	 */
	public static class SeacatConf {
		private String url;
		private String viewportId;
		private String viewportClass;
		private String viewportXpath;
		private String viewportRect;
		private String thumbSizes;
		private int waitTime;
		private boolean enableFull;
		private String pictureHome;
		private String prefix;
		private String suffix;
		private String postData;
		private boolean keepOrigin;

		public SeacatConf() {
			waitTime = -1;
			enableFull = false;
			keepOrigin = false;
			pictureHome = "/tmp";
		}
		public String getUrl() {
			return url;
		}
		public void setUrl(String url) {
			this.url = url;
		}
		public String getThumbSizes() {
			return thumbSizes;
		}
		public void setThumbSizes(String thumbSizes) {
			this.thumbSizes = thumbSizes;
		}
		public int getWaitTime() {
			return waitTime;
		}
		public void setWaitTime(int waitTime) {
			this.waitTime = waitTime;
		}
		public boolean isEnableFull() {
			return enableFull;
		}
		public void setEnableFull(boolean enableFull) {
			this.enableFull = enableFull;
		}
		public String getPictureHome() {
			return pictureHome;
		}
		public void setPictureHome(String pictureHome) {
			this.pictureHome = pictureHome;
		}
		public String getPrefix() {
			return prefix;
		}
		public void setPrefix(String prefix) {
			this.prefix = prefix;
		}
		public String getSuffix() {
			return suffix;
		}
		public void setSuffix(String suffix) {
			this.suffix = suffix;
		}
		public String getPostData() {
			return postData;
		}
		public void setPostData(String postData) {
			this.postData = postData;
		}
		public String getViewportId() {
			return viewportId;
		}
		public void setViewportId(String viewportId) {
			this.viewportId = viewportId;
		}
		public String getViewportClass() {
			return viewportClass;
		}
		public void setViewportClass(String viewportClass) {
			this.viewportClass = viewportClass;
		}
		public String getViewportXpath() {
			return viewportXpath;
		}
		public void setViewportXpath(String viewportXpath) {
			this.viewportXpath = viewportXpath;
		}
		public String getViewportRect() {
			return viewportRect;
		}
		public void setViewportRect(String viewportRect) {
			this.viewportRect = viewportRect;
		}
		public boolean isKeepOrigin() {
			return keepOrigin;
		}
		public void setKeepOrigin(boolean keepOrigin) {
			this.keepOrigin = keepOrigin;
		}
		
	}
	
	private String host;
	private int port;
	
	public Seacat() {
		this("localhost");
	}
	
	public Seacat(String host) {
		this(host,PORT);
	}
	
	public Seacat(String host,int port) {
		this.host = host;
		this.port = port;
	}
	
	/**
	 * capture web page
	 * @param conf
	 * @return
	 * @throws Exception
	 */
	public SeacatResult capture(SeacatConf conf) throws Exception {
		long t1 = System.currentTimeMillis();
		Socket socket = new Socket(host,port);
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		if (conf.getUrl()!=null) {
			bw.write("get "+conf.getUrl()+"\r\n");
		}
		if (conf.getViewportId()!=null) {
			bw.write("viewport-id "+conf.getViewportId()+"\r\n");
		}
		if (conf.getViewportClass()!=null) {
			bw.write("viewport-class "+conf.getViewportClass()+"\r\n");
		}
		if (conf.getViewportXpath()!=null) {
			bw.write("viewport-xpath "+conf.getViewportXpath()+"\r\n");
		}
		if (conf.getViewportRect()!=null) {
			bw.write("viewport-rect "+conf.getViewportRect()+"\r\n");
		}
		if (conf.getThumbSizes()!=null) {
			bw.write("thumb-sizes "+conf.getThumbSizes()+"\r\n");
		}
		if (conf.isEnableFull()) {
			bw.write("enable-full\r\n");
		}
		if (conf.getWaitTime()!=-1) {
			bw.write("wait-time "+conf.getWaitTime()+"\r\n");
		}
		if (conf.getPictureHome()!=null) {
			bw.write("picture-home "+conf.getPictureHome()+"\r\n");
		}
		if (conf.getPrefix()!=null) {
			bw.write("prefix "+conf.getPrefix()+"\r\n");
		}
		if (conf.getSuffix()!=null) {
			bw.write("suffix "+conf.getSuffix()+"\r\n");
		}
		if (conf.getPostData()!=null&&conf.getPostData().length()>0) {
			bw.write("content-length "+conf.getPostData().length()+"\r\n");
		}
		if (conf.isKeepOrigin()) {
			bw.write("keep-origin\r\n");
		}
		bw.write("\r\n");
		if (conf.getPostData()!=null&&conf.getPostData().length()>0) {
			bw.write(conf.getPostData());
		}
		bw.flush();
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8"));
		String line = br.readLine();
		char[] ca = line.toCharArray();
		int i = 0;
		while (i<ca.length&&ca[i]!=' ') i++;
		while (i<ca.length&&ca[i]==' ') i++;
		// get status code
		StringBuilder sb = new StringBuilder(4);
		while (i<ca.length&&ca[i]!=' ') {
			sb.append(ca[i]);
			i++;
		}
		int statusCode = NumberUtils.toInt(sb.toString());
		// get status text
		while (i<ca.length&&ca[i]==' ') i++;
		String statusText = line.substring(i);
		// get scid & geometry
		String scid = null;
		String geometry = null;
		while ((line=br.readLine())!=null) {
			if (line.length()==0) break;
			if (line.startsWith("SCID: ")) {
				scid = line.substring(6);
			} else if (line.startsWith("Geometry: ")) {
				geometry = line.substring(10);
			}
		}
		socket.close();
		//
		String pictureHome = null;
		String prefix = null;
		String[] suffixList = new String[0];
		if (scid!=null) {
			pictureHome = scid.substring(0,scid.lastIndexOf('/'));
			prefix = scid.substring(scid.lastIndexOf('/')+1);
			final String aPrefix = prefix;
			// get suffix list
			File[] list = new File(conf.getPictureHome()).listFiles(new FilenameFilter(){
				@Override
				public boolean accept(File dir, String name) {
					return name.startsWith(aPrefix);
				}
			});
			suffixList = new String[list.length];
			for (int k=0;k<list.length;k++) {
				suffixList[k] = list[k].getName().substring(prefix.length()+1);
			}
			Arrays.sort(suffixList);
		}
		long t2 = System.currentTimeMillis();
		SeacatResult result = new SeacatResult();
		result.setStatusCode(statusCode);
		result.setStatusText(statusText);
		result.setScid(scid);
		result.setElaspedTime(t2-t1);
		result.setGeometry(geometry);
		result.setPictureHome(pictureHome);
		result.setPrefix(prefix);
		result.setSuffixList(suffixList);
		return result;
	}
	
}

TestSeacat.java Download

package com.zhsoft88.commons.tests;

import com.zhsoft88.commons.Seacat;
import com.zhsoft88.commons.Seacat.SeacatConf;
import com.zhsoft88.commons.Seacat.SeacatResult;

/**
 * seacat tester
 * @author zhsoft88
 *
 * @since 2008-12-13
 */
public class TestSeacat {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		Seacat seacat = new Seacat();
		{
			// get snapshot by id
			SeacatConf conf = new SeacatConf();
			conf.setUrl("http://www.google.com");
			conf.setViewportId("gbar");
			conf.setThumbSizes("160x120");
			conf.setKeepOrigin(true);
			SeacatResult result = seacat.capture(conf);
			result.dump();
		}
		{
			// get snapshot by class
			SeacatConf conf = new SeacatConf();
			conf.setUrl("http://news.google.com");
			conf.setViewportClass("lh");
			conf.setThumbSizes("160x120");
			conf.setEnableFull(true);
			conf.setKeepOrigin(true);
			SeacatResult result = seacat.capture(conf);
			result.dump();
		}
		{
			// get snapshot by xpath
			SeacatConf conf = new SeacatConf();
			conf.setUrl("http://news.google.com");
			conf.setViewportXpath("//*[@id='topSection']");
			conf.setThumbSizes("160x120");
			conf.setKeepOrigin(true);
			SeacatResult result = seacat.capture(conf);
			result.dump();
		}
		{
			// get snapshot by specific region
			SeacatConf conf = new SeacatConf();
			conf.setUrl("http://news.google.com");
			conf.setViewportRect("200 200 400 300");
			conf.setThumbSizes("160x120");
			conf.setKeepOrigin(true);
			SeacatResult result = seacat.capture(conf);
			result.dump();
		}
	}

}

Products: Sealion Seacat Seaflower Seaspider Seasnipe Seastar Seadog Jiong WBXL Xultray webapp
iDocSet iDocSetHelper Blink templateJS
(C) 2017 ZHUATANG.COM, All rights reserved

update: 2013-06-06