`
max_annie
  • 浏览: 22275 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用JSoup生成本地HTML

 
阅读更多
实现功能:
1.根据URL抓取网页
2.添加(修改)网页内容
3.下载与网页相关的js,css,img,flash,iframe等
4.修改js,css,img,flash,iframe的路径
5.添加注释<!-- saved from url=("+new DecimalFormat("0000").format(url.length())+")"+url+" -->,网页不会弹出限制运行脚本提示
6.按照编码方式生成本地页面

工具类:

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class CreateHtmlJsoup {
	public static void main(String[] args) {
		makeHeatMapHtml();
	}

	/**
	 * 生成HTML到本地的临时目录中
	 */
	public static void makeHeatMapHtml() {
		System.out.println("下载页面开始......");
		long start = System.currentTimeMillis();
		String url = "";//
		String filepath = "";// 
		String filename = "";// 
		String ecoding = "";// 
		
		url = "http://finance.people.com.cn/GB/index.html";
		filepath = "F:\\people.temp\\";
		filename = "index.html";// 文件名称
		ecoding = "gbk";// 编码格式
		if (copyURLToHtml(url, filepath, filename, ecoding)) {// 如果页面访问成功,下载URL网页到本地临时目录
			copyDirToDir(filepath, StringUtils.replace(filepath, ".temp",
					""));// 把临时目录中的文件复制到本地
			delTempFile(filepath);// 删除临时目录
		} 

		System.out.println("下载页面完成 ,用时"
				+ (System.currentTimeMillis() - start) / 1000 / 60 + "分钟");
	}

	/**
	 * 文件夹copy
	 * 
	 * @param filepath
	 */
	protected static void copyDirToDir(String orgPath, String destPath) {
		File srcDir = new File(orgPath);
		File destDir = new File(destPath);
		if (srcDir.exists()) {
			try {
				FileUtils.copyDirectory(srcDir, destDir);
			} catch (IOException e) {
				System.out.println("复制临时目录失败");
			}
		}
	}

	/**
	 * 删除临时目录
	 * 
	 * @param filepath
	 */
	protected static void delTempFile(String filepath) {
		File tempFile = new File(filepath);
		try {
			FileUtils.deleteDirectory(tempFile);
		} catch (IOException e) {
			System.out.println("删除临时目录失败");
		}
	}

	/**
	 * 生成本地HTML
	 * 
	 * @param url
	 *            链接地址
	 * @param filepath
	 *            生成文件路径
	 * @param filename
	 *            生成文件名称
	 * @param ecoding
	 *            编码方式
	 * @return
	 */
	private static boolean copyURLToHtml(String url, String filepath, String filename,
			String ecoding) {
		boolean flag = false;
		Document doc;
		doc = copyURLToHtmlDoc(url, filename, filepath, ecoding, 5 * 60000);// 根据Url抓取页面放入document对象
		if (null == doc) {
			System.out.println("下载页面" + url + "失败......");
			return flag;
		}
		String content = "<script type='text/javascript' src='../../render.js' charset='utf-8' ></script>"
			+ "<script type='text/javascript'>"
			+ "_RunTerrenStyle();"
			+ "</script>";
		doc = appendLink(doc, "body", content);// 在head标签中加载js
		flag = makeHtmlByDoc(filepath, filename, doc, ecoding);// 生成html文件
		System.out.println("下载页面" + url + "成功......编码: " + ecoding);
		return flag;
	}

	/**
	 * 根据url抓取网页中找到css样式,js,img链接地址及文件名
	 * 
	 * @param doc
	 *            jsoup.nodes.Document
	 * @return List<StyleSheet>
	 */
	public static List<HtmlFileLink> getHtmlFileLink(Document doc) {
		List<HtmlFileLink> HtmlFileLinks = new ArrayList<HtmlFileLink>();
		String postfix = "";// 文件后缀名
		int index = 0; // 用于文件名
		Elements importcss = doc.select("link[href]");// 找到document中带有link标签的元素
		for (Element link : importcss) {
			postfix = "css";
			if (link.attr("rel").equals("stylesheet")) {// 如果rel属性为HtmlFileLink
				String href = link.attr("abs:href");// 得到css样式的href的绝对路径
				// 如http://news.baidu.com/resource/css/search.css
				String filename = postfix + index + "." + postfix;//
				HtmlFileLinks.add(new HtmlFileLink(href, filename, postfix));
				index++;
			}
		}
		Elements media = doc.select("[src]");
		for (Element link : media) {
			if (link.tagName().equals("img")) {
				String src = link.attr("abs:src");
				postfix = getPostfix(src);
				String filename = postfix + index + "." + postfix;
				HtmlFileLinks.add(new HtmlFileLink(src, filename, postfix));
				index++;
			}
			if (link.tagName().equals("input")) {
				if (link.attr("type").equals("Image")) {
					String src = link.attr("abs:src");
					postfix = getPostfix(src);
					String filename = postfix + index + "." + postfix;
					HtmlFileLinks.add(new HtmlFileLink(src, filename, postfix));
					index++;
				}
			}
			if (link.tagName().equals("javascript")
					|| link.tagName().equals("script")) {
				String src = link.attr("abs:src");
				postfix = getPostfix(src);
				String filename = postfix + index + "." + postfix;
				HtmlFileLinks.add(new HtmlFileLink(src, filename, postfix));
				index++;
			}
			if (link.tagName().equals("iframe")) {
				String src = link.attr("abs:src");
				postfix = getPostfix(src);
				String filename = postfix + index + ".html";
				HtmlFileLinks.add(new HtmlFileLink(src, filename, postfix));
				index++;
			}
			if (link.tagName().equals("embed")) {
				String src = link.attr("abs:src");
				postfix = getPostfix(src);
				String filename = postfix + index + "." + postfix;
				HtmlFileLinks.add(new HtmlFileLink(src, filename, postfix));
				index++;
			}
		}
		return HtmlFileLinks;
	}

	/**
	 * 去掉HTML中的A标签链接地址
	 * 
	 * @param doc
	 */
	public static void removeHref(Document doc) {
		doc.select("a").removeAttr("href");// 去掉a的链接
		doc.select("img").removeAttr("onclick"); // 去掉图片onclick事件
		doc.select("input[type=submit]").attr("type", "button");// submit按钮改为普通按钮
		doc.select("input[type=button]").removeAttr("onclick"); // 去掉按钮的onclick事件
		doc.select("area").removeAttr("href");// 去掉area的链接
	}

	/**
	 * 修改抓取网页中的css样式表链接地址,改为相对路径
	 * 
	 * @param doc
	 *            jsoup.nodes.Document
	 * @param list
	 *            List<HtmlFileLink>
	 */
	public static void renameHref(Document doc) {
		List<HtmlFileLink> list = getHtmlFileLink(doc);
		if (list.size() == 0) {
			return;
		}
		Elements imports = doc.select("link[href]");
		for (Element link : imports) {
			for (HtmlFileLink ss : list) {
				if (link.attr("abs:href").equals(ss.getHref())) {
					link.attr("href", ss.getFilename());
				}
			}
		}
		Elements media = doc.select("[src]");
		for (Element link : media) {
			for (HtmlFileLink ss : list) {
				if (link.attr("abs:src").equals(ss.getHref())) {
					link.attr("src", ss.getFilename());
				}
			}
		}
	}

	/**
	 * 在网页的元素中添加对象
	 * 
	 * @param doc
	 * @param tag
	 *            标签
	 * @param content
	 *            内容
	 * @return
	 */
	public static Document appendLink(Document doc, String tag, String content) {
		Element element = doc.select(tag).first();
		element.append(content);
		return doc;
	}

	/**
	 * 根据u网页中css、js、img链接地址及文件名生成本地文件
	 * 
	 * @param doc
	 * @param filepath
	 * @param timeout
	 * @throws IOException
	 */
	public static void makeHtmlLinkFile(Document doc, String filepath,
			int timeout) {
		File file = new File(filepath);
		if (file.exists()) {
			try {
				FileUtils.cleanDirectory(new File(filepath));
			} catch (IOException e) {
				System.out.println("清空文件夹 :" + filepath + " 错误");
			}
		}
		List<HtmlFileLink> list = getHtmlFileLink(doc);// 根据url抓取网页中找到css样式链接地址及文件名
		for (HtmlFileLink ss : list) {
			/**
			 * jsoup不支持访问js文件所以改用apache commons的fileUtil生成js和css文件
			 */
			try {
				FileUtils.copyURLToFile(new URL(ss.getHref()), new File(
						filepath + ss.getFilename()), timeout, timeout);
			} catch (MalformedURLException e) {
				System.out.println("地址 :" + ss.getHref() + " 链接错误");
				continue;
			} catch (IOException e) {
				System.out.println("地址 :" + ss.getHref() + " 链接超时");
				continue;
			}
		}
	}

	/**
	 * 根据Url抓取页面返回document对象
	 * 
	 * @param url
	 *            链接地址
	 * @param filename
	 *            文件名称
	 * @param filepath
	 *            文件生成路径
	 * @param ecoding
	 *            编码格式
	 * @param timeout
	 *            延时
	 * @return boolean
	 */
	public static Document copyURLToHtmlDoc(String url, String filename,
			String filepath, String ecoding, int timeout) {
		Document doc = null;
		try {

			doc = Jsoup.connect(url).timeout(timeout).get();// 根据Url抓取页面放入document对象
			makeHtmlLinkFile(doc, filepath, timeout);// 根据u网页中css、js、img链接地址及文件名生成本地文件
			renameHref(doc);// 把页面中link标签中的href属性改为本地的相对路径,正确加载css样式
		    removeHref(doc);// 去掉A链接
		    doc.select("html").before("<!-- saved from url=("+new DecimalFormat("0000").format(url.length())+")"+url+" -->");
		} catch (IOException e) {
			System.out.println("访问页面地址 : " + url + "链接超时");
			System.out.println("访问页面地址 : " + url + "失败");
			return doc;
		} catch (IllegalArgumentException e) {
			System.out.println("访问页面地址 : " + url + "输入错误");
			System.out.println("访问页面地址 : " + url + "失败");
			return doc;
		}
		System.out.println("访问页面地址 : " + url + "成功");
		return doc;
	}

	/**
	 * 根据url抓取网页,并生成本地的html文件 解决了css样式问题
	 * 
	 * @param url
	 *            链接地址
	 * @param filename
	 *            文件名称
	 * @param filepath
	 *            文件生成路径
	 * @param ecoding
	 *            编码格式
	 * @return boolean
	 */
	public static Document copyURLToHtmlDoc(String url, String filename,
			String filepath, String ecoding) {
		return copyURLToHtmlDoc(url, filename, filepath, ecoding, 60000);
	}

	/**
	 * 过滤文件名,得到文件后缀
	 * 
	 * @param filename
	 *            文件名
	 * @return
	 */
	public static String getPostfix(String filename) {
		filename = StringUtils.substringAfterLast(filename, ".");
		filename = StringUtils.substringBefore(filename, "?");
		filename = StringUtils.substringBefore(filename, "/");
		filename = StringUtils.substringBefore(filename, "\\");
		filename = StringUtils.substringBefore(filename, "&");
		filename = StringUtils.substringBefore(filename, "$");
		filename = StringUtils.substringBefore(filename, "%");
		filename = StringUtils.substringBefore(filename, "#");
		filename = StringUtils.substringBefore(filename, "@");
		return filename;
	}

	/**
	 * 根据抓取网页的document对象生成html文件
	 * @version 0.1 解决了window 换行符问题
	 * @param filepath
	 * @param filename
	 * @param doc
	 * @param ecoding
	 * @return
	 */
	public static boolean makeHtmlByDoc(String filepath, String filename,
			Document doc, String ecoding) {
		boolean flag = false;
		try {
			String html = doc.html();
			html = html.replaceAll("\n", "\r\n");
			FileUtils.writeStringToFile(new File(filepath + filename), html, ecoding);
			flag = true;
		} catch (IOException e) {
			System.out.println("生成页面错误 文件: " + filepath + filename);
		}// 生成本地的html文件
		System.out.println("生成html页面 文件 : " + filepath + filename + "完成");
		return flag;
	}
}



实体类
public class HtmlFileLink {
	private String href;
	private String filename;
	private String type;
	/**
	 * @return the type
	 */
	public String getType() {
		return type;
	}
	/**
	 * @param type the type to set
	 */
	public void setType(String type) {
		this.type = type;
	}
	public HtmlFileLink(String href, String filename,String type) {
		super();
		this.href = href;
		this.filename = filename;
		this.type = type;
	}
	public HtmlFileLink() {
		super();
	}
	/**
	 * @return the href
	 */
	public String getHref() {
		return href;
	}
	/**
	 * @param href the href to set
	 */
	public void setHref(String href) {
		this.href = href;
	}
	/**
	 * @return the filename
	 */
	public String getFilename() {
		return filename;
	}
	/**
	 * @param filename the filename to set
	 */
	public void setFilename(String filename) {
		this.filename = filename;
	}
}

分享到:
评论

相关推荐

    android使用jsoup 解析html文件

    使用`Jsoup.parse()`方法解析HTML字符串,得到一个`Document`对象,表示整个HTML文档的结构: ```java Document document = Jsoup.parse(htmlContent); ``` 3. **选择和操作HTML元素** `jsoup`提供了丰富的...

    Jsoup解析html中文文档

    1. **从URL、文件或字符串中解析HTML**:无论是网络上的HTML页面还是本地文件,甚至是字符串形式的HTML文本,jsoup都能够轻松解析。 2. **使用DOM或CSS选择器查找数据**:支持DOM方式的节点查询,也支持使用CSS选择...

    用Jsoup解析html的所有jar包

    Jsoup的核心功能在于它能够通过连接到一个URL或读取本地HTML文件来获取HTML内容。例如: ```java import org.jsoup.Jsoup; import org.jsoup.nodes.Document; public class JsoupExample { public static void ...

    jsoup操作手册 API

    无论是从字符串、URL还是本地文件中加载HTML,还是使用DOM或CSS选择器提取数据,jsoup都能提供简洁、高效的解决方案。对于任何需要解析和操作HTML的Java项目而言,jsoup都是一个不可或缺的强大助手。

    jsoup java解析html

    JSoup能够解析来自网络或本地文件系统的HTML文档,将其转化为一个可操作的`org.jsoup.nodes.Document`对象。这个对象就像一个完整的DOM树,你可以通过这个树来遍历和修改HTML结构。 ```java import org.jsoup.Jsoup...

    jsoup中文教程

    Jsoup同样可以加载本地文件系统中的HTML文档。使用`Jsoup.parse(File input, String charsetName, String baseUri)`方法,可以从文件中读取HTML内容,构建Document对象。 #### 数据抽取 Jsoup支持通过DOM方法来遍历...

    jsoup 解析html

    - **连接与下载**:JSoup不仅用于解析本地文件,还可以直接连接到URL,下载并解析远程网页内容。 - **安全处理**:JSoup对HTML进行了安全处理,避免了XSS(跨站脚本攻击)等安全问题。 2. **核心API** - **Jsoup...

    jsoup-1.11.3.jar

    jsoup能够高效地解析HTML文档,无论是从网络抓取的网页,还是存储在本地的HTML文件,都可以轻松处理。通过使用DOM(Document Object Model)模型,开发者可以像操作XML文档一样,对HTML元素进行查找、遍历和修改。...

    使用java-jsoup解析html页面内容,爬取想要的信息(如号段)

    jsoup 可以从包括字符串、URL 地址以及本地文件来加载 HTML 文档,并生成 Document 对象实例。 如:我们可以通过访问号段查询页面,获取到手机号段信息,并提取信息存储供自身的业务使用。 附件提供了详细的介绍,并...

    jsoup.jar包

    6. **连接功能**:除了解析本地HTML字符串,jsoup还可以直接连接到网络上的URL,下载并解析HTML页面,这对于网络爬虫或者自动化数据抓取任务来说,是一个非常实用的功能。 7. **错误处理**:在处理HTML时,jsoup会...

    jsoup-1.8.1

    这个版本的jsoup提供了高效且易于使用的接口,使得开发者可以方便地处理网页内容,无论是从网络抓取还是从本地文件系统读取。jsoup的出现解决了Java开发者在处理HTML时遇到的许多难题,比如解析不规范的HTML、提取...

    spring boot+java +jsoup+ 爬虫

    在图片爬取过程中,首先,我们需要设置一个起始URL,然后使用Jsoup解析该页面的HTML内容。通过选择器如`img[src]`,可以找到所有的图片链接。接下来,可以使用Java的HttpURLConnection或HttpClient库,向每个图片URL...

    java爬虫jsoup1.11.3源码

    JSoup不仅可以解析本地的HTML文件,还能直接连接到指定的URL,下载并解析HTML内容。这使得JSoup成为了一个简单的网页抓取工具。通过`Jsoup.connect(url).get()`,开发者就能获取到远程网页的HTML,然后进行后续处理...

    Android输出html格式的文件

    以上就是使用Jsoup在Android中生成并保存HTML文件的基本流程。通过扩展这个基础,可以构建更复杂的功能,如动态生成图表、嵌入样式表和脚本,甚至实现与服务器的交互,生成自定义的报告文件。记住,始终确保遵循最佳...

    jSoup1.8.1jar包

    6. **连接功能**:除了解析本地文件,jsoup还可以直接连接到URL,下载并解析远程HTML页面,从而实现网络数据的获取。 在项目中,`jsoup-1.8.1.jar`是这个库的特定版本,包含了所有必要的类和方法来实现上述功能。将...

    关于android之Jsoup解析

    Jsoup支持多种方式来加载HTML文档,这包括从字符串、URL地址以及本地文件加载文档,并生成`Document`对象实例。 ##### 示例代码: ```java // 直接从字符串中输入HTML文档 String html = "&lt;html&gt;&lt;head&gt;&lt;title&gt;开源...

    Jsoup Cookbook(中文版)

    Jsoup 支持多种方式解析 HTML 文档,包括直接解析 URL 地址、解析本地文件、解析纯文本等。其解析引擎非常智能,能够根据输入的 HTML 生成一个结构良好的文档对象模型(DOM)。 **示例代码**: ```java String html...

    jsoup-1.11.2.jar 下载

    1. **HTML解析**:jsoup能够解析HTML文档,并生成一个与原始文档结构一致的DOM树。这使得开发者可以像操作DOM节点一样轻松地遍历和修改HTML内容。 2. **选择器API**:jsoup支持CSS选择器,允许开发者使用类似于...

    Java中使用开源库JSoup解析HTML文件实例

    使用JSoup,你可以从不同的源获取HTML内容,包括直接从URL下载、读取本地文件或使用字符串形式的HTML代码。一旦获取了HTML内容,JSoup允许你进行复杂的数据提取和修改。你不仅能够提取特定的元素和属性,还能利用CSS...

Global site tag (gtag.js) - Google Analytics