日期:2014-05-17  浏览次数:20593 次

HTMLParser入门_01_网络爬虫的雏形_解析文章和处理文章中的图片
package com.jadyer.httpclient;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.nodes.TagNode;
import org.htmlparser.nodes.TextNode;
import org.htmlparser.tags.ImageTag;
import org.htmlparser.util.NodeList;

/**
 * HTMLParser入门_01_网络爬虫的雏形_解析文章和处理文章中的图片
 * @see ---------------------------------------------------------------------
 * @see 所有jar如下
 * @see commons-io-2.3.jar
 * @see commons-land-2.3.jar
 * @see commons-codec-1.6.jar(以下7个jar取自HttpClient官网下载的httpcomponents-client-4.2.1-bin.zip)
 * @see commons-logging-1.1.1.jar
 * @see fluent-hc-4.2.1.jar
 * @see httpclient-4.2.1.jar
 * @see httpclient-cache-4.2.1.jar
 * @see httpcore-4.2.1.jar
 * @see httpmime-4.2.1.jar
 * @see filterbuilder.jar(以下5个jar取自HTMLParser官网下载的HTMLParser-2.0-SNAPSHOT-bin.zip)
 * @see htmllexer.jar
 * @see htmlparser.jar
 * @see sitecapturer.jar
 * @see thumbelina.jar
 * @see ---------------------------------------------------------------------
 * @see 网络爬虫的雏形
 * @see 通过本文的三个方法,就可以初步实现一个网络爬虫
 * @see 比如有个后台管理系统,可添加待爬虫的技术文章,输入参数为文章URL,输出参数为文章中的实际内容
 * @see 并且它还会下载文章内容中的图片,并修改内容中的图片URL为本地的绝对路径,使得文章图片正常显示
 * @see 接下来就是在前台显示文章了,至于怎么显示,随心所欲喽..
 * @see 至于如何获取文章标题,作者,关键字,总体描述等信息,可参考我的下面这一篇文章
 * @see http://blog.csdn.net/jadyer/article/details/8656477
 * @see ---------------------------------------------------------------------
 * @create Mar 10, 2013 4:05:55 PM
 * @author 玄玉<http://blog.csdn/net/jadyer>
 */
public class SpiderDemo {
	private static final String articleURI = "http://www.ibm.com/developerworks/cn/java/j-javaroundtable/index.html";
	private static final String localHTML = "D:/Download/localHTML.html";
	
	/**
	 * 下载文章
	 */
	private static void downloadArticle() throws Exception {
		HttpClient httpClient = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(articleURI);
		try {
			HttpResponse response = httpClient.execute(httpGet);
			HttpEntity entity = response.getEntity();
			if(null != entity){
				String responseContent = EntityUtils.toString(entity, "UTF-8");
				EntityUtils.consume(entity);
				//文章内容写到本地(IOUtils干完活儿会自动关闭IO流)
				IOUtils.write(responseContent, new FileOutputStream(localHTML), "UTF-8");
			}
		}finally{
			httpClient.getConnectionManager().shutdown();
		}
	}
	
	
	/**
	 * 下载文章内容中的图片到本地
	 */
	private static void downloadArticleImage() throws Exception {
		//加载文章整理
		String html = IOUtils.toString(new FileInputStream(localHTML), "UTF-8");
		//获取文章内容,这里是通过分析文章<body>中的特征来获取内容的
		String article = StringUtils.substringBetween(html, "<!-- MAIN_COLUMN_CONTENT_BEGIN -->", "<!-- CMA");
		System.out.println("文章内容:" + article);
		Parser parser = new Parser();
		parser.setInputHTML(article);
		//提取所有的<img>标签
		//这里使用了内置的NodeClassFilter,它会根据节点类型来过滤,这里过滤的是ImageTag节点类型
		NodeList imageTags = parser.parse(new NodeClassFilter(ImageTag.class));
		for(int i=0; i<imageTags.size(); i++){
			ImageTag it = (ImageTag)imageTags.elementAt(i);
			//it.getImageURL()即<img>中的src属性值
			System.out.println("图片链接:" + it.getImageURL());
			//合成图片的绝对路径http://www.ibm.com/developerworks/cn/java/j-javaroundtable/ + it.getImageURL()
			String absoluteURL = articleURI.substring(0, articleURI.lastIndexOf("/")+1) + it.getImageURL();
			System.out.println(