java实现的简单网页爬虫:Servlet + MySQL5.5(二)

java实现的简单网页爬虫:Servlet + MySQL5.5(二)


java实现的简单网页爬虫:Servlet + MySQL5.5 进行了改善,将爬取的网址,进行分类保存。

<span style="font-size:14px;">/*
 * 
 * @author Administrator
 * 
 * 在JavaSpider 1.3 的基础上,对爬取的网址,进行分类存储
 * 
 * 1,把temp_url 临时网址,存储到临时表 temp_url 中;
 * 2,把target_url 目标网址,存储到目标表 target_url 中;
 *
 */</span>

项目中用到的所有文件,可以在资源里面下载 :

http://download.csdn.net/detail/reggergdsg/9406609


简单看一下效果图:

java实现的简单网页爬虫:Servlet + MySQL5.5(二)_第1张图片


关键代码一:JavaSpider_2016/src/com/spider/servlet/SaveToDifferentDatabase_JavaSpider_1_5_Servlet.java  servlet控制器类


package com.spider.servlet;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.spider.Model.Target_url;
import com.spider.Model.Temp_url;
<span style="font-size:14px;"></span><pre name="code" class="java">import com.spider.java.JavaSpider_1_5;
import com.spider.service.JavaSpider_1_5_Service;
import com.spider.service.impl.JavaSpider_1_5_ServiceImpl;

/**
 * 
 * @author Administrator
 * 
 * 在JavaSpider 1.3 的基础上,对爬取的网址,进行分类存储
 * 
 * 1,把temp_url 临时网址,存储到临时表 temp_url 中;
 * 2,把target_url 目标网址,存储到目标表 target_url 中;
 *
 */

@SuppressWarnings("serial")
public class SaveToDifferentDatabase_JavaSpider_1_5_Servlet extends HttpServlet{

	//定义service层接口对象
	JavaSpider_1_5_Service javaSpider_1_5_Service = new JavaSpider_1_5_ServiceImpl();

	//service层接口对象 的 setter方法 
	public void setJavaSpider_1_5_Service(JavaSpider_1_5_Service javaSpider_1_5_Service) {
		
		//测试输出
		System.out.println("JavaSpider_1_5 版本 JavaSpider_1_5_Service 接口对象 的 setter 方法执行了... ");
		
		this.javaSpider_1_5_Service = javaSpider_1_5_Service;
	}
	
	//实现doPost方法
	public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
		
		//设置相应信息的编码方式
		response.setCharacterEncoding("UTF-8");
		
		//定义一个String类型的变量,用来表示用户输入的URL
		String URL = "";
		
		//定义一个String类型的变量,用来表示用户输入的URL
		int LEVEL = 0;
		
		//定义一个String类型的变量,用来表示返回客户端的提示信息
		String message = "";
		
		//生成Temp_url对象
		Temp_url url_temp = new Temp_url();
		
		//生成Target_url对象
		Target_url target_url = new Target_url();
		
		//定义一个Map,用来封装所有的URL网址
		Map<Integer,String> urls = new HashMap<Integer,String>();
		
		//
		Map<Integer,String> urls_rs = new HashMap<Integer,String>();
		
		//生成JavaSpider_1_3_URLParser对象
		JavaSpider_1_5 javaSpider_1_5 = new JavaSpider_1_5();
		
	    //生成日期对象
	    Date current_date = new Date();
	    
	    //设置日期格式化样式为:yyyy-MM-dd
	    SimpleDateFormat  SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
	    
	    //格式化当前日期
	    SimpleDateFormat.format(current_date.getTime());
	    
		//在request请求域中获取参数
	    LEVEL = Integer.parseInt(request.getParameter("LEVEL"));
		URL = request.getParameter("URL");
		
		//测试输出
		System.out.println("在servlet中接收到的用户输入的网址:" + URL);

		if(!"".equals(URL)){
			
			//测试输出
			System.out.println(" 在servlet中 ,!''.equals(URL):如果URL不为空,进入if语句...");
			
		    //获取所有的URL网址
		    urls = javaSpider_1_5.getFormatCode_1_5(URL);
		    
		    //封装url实体
		    for(int i=0;i<urls.size();i++){
		    	
		    	/*
		    	 * 对网址进行分类存储,如果是临时网址,则保存到临时表;如果是目标网址,则保存到目标表
		    	 */
		    	
		    	//如果是目标网址
		    	if(urls.get(i).toLowerCase().endsWith(".html")){
			    	
		    		target_url.setTempurl(urls.get(i));
		    		target_url.setLevel(LEVEL);
			    	
			    	//调用业务逻辑处理对象,完成数据保存到数据库的业务逻辑
			    	javaSpider_1_5_Service.saveToDatabaseTarget_url(target_url);
			    	
					//测试输出
					System.out.println("目标网址保存到目标数据库  target_url ");
		    		
		    	}
		    	//如果是临时网址
		    	else{
			    	
			    	url_temp.setTempurl(urls.get(i));
			    	url_temp.setLevel(LEVEL);
			    	
			    	//调用业务逻辑处理对象,完成数据保存到数据库的业务逻辑
			    	javaSpider_1_5_Service.saveToDatabase(url_temp);
			    	
					//测试输出
					System.out.println("临时网址保存到临时数据库  url_temp ");
		    		
		    	}
		    	
		    }
				
			message = "文件保存完成...";
				
			//把信息保存到request请求域中,传递到客户端
			request.setAttribute("message", message);
				
			//跳转到SpiderIndex.jsp页面
			request.getRequestDispatcher("WEB-INF/spider/Success.jsp").forward(request, response);

		}
		
		else{
			
			urls_rs = javaSpider_1_5_Service.getAllUrlsOfLevel(LEVEL);
			
		    //封装url实体
		    for(int i=0;i<urls_rs.size();i++){
		    	
		    	urls = javaSpider_1_5.getFormatCode_1_5(urls_rs.get(i));
		    	
		    	//测试输出
		    	System.out.println("查询结果集中的网址 urls_rs.get(i) = " + urls_rs.get(i));
		    	System.out.println("新爬取的网址 urls.get(i) = " + urls.get(i));
		    	
		    	for(int j=0;j<urls.size();j++){
		    		
			    	/*
			    	 * 对网址进行分类存储,如果是临时网址,则保存到临时表;如果是目标网址,则保存到目标表
			    	 */
			    	
			    	//如果是目标网址
			    	if(urls.get(i).toLowerCase().endsWith(".html")){
				    	
			    		target_url.setTempurl(urls.get(i));
			    		target_url.setLevel(LEVEL);
				    	
				    	//调用业务逻辑处理对象,完成数据保存到数据库的业务逻辑
				    	javaSpider_1_5_Service.saveToDatabaseTarget_url(target_url);
			    		
			    	}
			    	//如果是临时网址
			    	else{
				    	
				    	url_temp.setTempurl(urls.get(i));
				    	url_temp.setLevel(LEVEL);
				    	
				    	//调用业务逻辑处理对象,完成数据保存到数据库的业务逻辑
				    	javaSpider_1_5_Service.saveToDatabase(url_temp);
			    		
			    	}
		    		
		    	}
		    }
				
				message = "文件保存完成...";
				
				//把信息保存到request请求域中,传递到客户端
				request.setAttribute("message", message);
				
				//跳转到SpiderIndex.jsp页面
				request.getRequestDispatcher("WEB-INF/spider/Success.jsp").forward(request, response);
			
		}
	}
	

	//实现doGet方法
	public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
		
		//设置相应信息的编码方式
		response.setCharacterEncoding("UTF-8");	
		
		this.doPost(request, response);
		
	}
	
}

 
 
关键代码二:/JavaSpider_2016/src/com/spider/java/JavaSpiderBase_1_5.java  爬虫核心接口

package com.spider.java;

import java.io.IOException;
import java.util.Map;

import org.apache.http.client.ClientProtocolException;

public interface JavaSpiderBase_1_5 {
	
	//带参数的方法 JavaSpider_1_5版本
	public Map<Integer,String> getFormatCode_1_5(String URL) throws ClientProtocolException, IOException;
	
}

关键代码三:/JavaSpider_2016/src/com/spider/java/JavaSpider_1_5.java  爬虫核心接口实现类

package com.spider.java;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

@SuppressWarnings("deprecation")
public class JavaSpider_1_5 implements JavaSpiderBase_1_5{

	@Override
	public Map<Integer, String> getFormatCode_1_5(String URL) throws ClientProtocolException, IOException {

		
		//创建HttpClient
		HttpClient httpClient = new DefaultHttpClient();
		//获取HttpGet对象
		HttpGet httpGet = new HttpGet(URL);
		//
		@SuppressWarnings("unused")
		StringBuffer stringBuffer = new StringBuffer();
		//
		HttpResponse httpResoponse = httpClient.execute(httpGet);
		//
		BufferedReader bufferedReader;
		//定义一个Map,用来封装所有的URL
		Map<Integer,String> urls = new HashMap<Integer,String>();

		//生成JavaSpider_1_4_URLParser对象
		JavaSpider_1_4_URLParser javaSpider_1_4_URLParser = new JavaSpider_1_4_URLParser();
		
		if(HttpStatus.SC_OK == httpResoponse.getStatusLine().getStatusCode()){
			//
			HttpEntity httpEntity = httpResoponse.getEntity();
			//
			if(httpEntity != null){
				
				bufferedReader = new BufferedReader(new InputStreamReader(httpEntity.getContent(),"UTF-8"));
				
				//bufferedReader按行读取
				String line = "";
				
				//if(httpEntity.getContentLength() > 0 ){
				if(httpEntity.getContent() != null && httpEntity.getContentLength() > 0){

					stringBuffer = new StringBuffer((int) httpEntity.getContentLength());
					
					int z = 0;

					while((line = bufferedReader.readLine()) != null){

						//判断得到的目标网址是否为空
						if(!"".equals(javaSpider_1_4_URLParser.parserURL(line, URL))){
							
							//封装到数组中
							
							urls.put(z, javaSpider_1_4_URLParser.parserURL(line, URL));
							
							System.out.println("if在JavaSpider中测试输出获取到的所有网址:" + urls.get(z));
							
							z++;
						}
					
					}
				}
				
				//如果httpEntity.getContent() != null && httpEntity.getContentLength() == -1
				else{
					//测试输出
					System.out.println("进入if...进入条件:httpEntity.getContent() != null || httpEntity.getContentLength() == -1");

					//stringBuffer = new StringBuffer((int) httpEntity.getContentLength());
					//把长度写死
					stringBuffer = new StringBuffer(1024);
					
					int z = 0;

					while((line = bufferedReader.readLine()) != null){
						
						//判断得到的目标网址是否为空
						if(!"".equals(javaSpider_1_4_URLParser.parserURL(line, URL))){
							
							//封装到数组中
							
							urls.put(z, javaSpider_1_4_URLParser.parserURL(line, URL));
							
							System.out.println("else在JavaSpider中测试输出获取到的所有网址:" + urls.get(z));
							
							z++;
						}
					
					}
				}
			}
			if(httpEntity != null){
				//
				httpEntity.consumeContent();
			}
		}
		
		//返回Map
		return urls;

	}
}

关键代码四:/JavaSpider_2016/src/com/spider/java/JavaSpider_1_5_HTMLParser.java  HTML页面抽取工具类

package com.spider.java;

public class JavaSpider_1_5_HTMLParser {
	//
	public String parserHTML(String line){
		
		//定义一个String类型的变量parseredLine,用来表示处理以后的line
		String parseredLine = "";
		//第一次抽取后的子串
		String subString = "";
		//第二次抽取后的子串
		String sub_subString = "";
		//第三次抽取后的子串
		String sub_sub_subString = "";
		int i = line.indexOf('<'); 
		int j = line.lastIndexOf('<');
		int k = line.indexOf('>');

		//1,如果字符<第一次出现的索引和最后一次出现的索引值相等,说明这一行,只有一对<></> 这种闭合的HTML标签;
		//此时只需要把这个标签删除掉就行,我们可以使用String类的subString方法截取我们需要的信息;
		if(i == j && i != -1){
			//这种情况下, 我们还要再判断,这个标签是不是位于行首;
			if(i == 0 ){
				//System.out.println(""); //简化处理
			}
			else{
				//System.out.println("");  //简化处理,暂时不考虑<br>这种单独的标签
			}
				
		}
		//如果字符< 第一次出现的索引和最后一次出现的索引值不相同,说明这一行,有2对<></>或者多对, 这样的闭合的HTML标签;
		//2,如果有2对闭合的HTML标签;此时我们需要删除这2对HTML标签;这里简化步骤,只考虑闭合标签位于首尾的情况;
		else if(i != j){
			//第一次抽取
			subString = line.substring(k+1, j);
			//第二次抽取
			//第二次抽取的时候,需要考虑2个标签的特殊情况,也就是title、link这种标签,虽然符合条件,但是不抽取这种值。
			int y = subString.lastIndexOf('<');
			int z = subString.indexOf('>');
			if(y > -1){
				//此时还要考虑只有3个HTML标签的特殊情况
				if(subString.contains("<title") || subString.contains("<link" )){
					sub_subString = subString.substring(z+1, y);
				}
				else{
					sub_subString = subString.substring(z+1, y);
					if(sub_subString != null && (sub_subString.startsWith("0") || sub_subString.startsWith("1") 
							|| sub_subString.startsWith("2") 
							|| sub_subString.startsWith("3") || sub_subString.startsWith("4") || sub_subString.startsWith("5")
							|| sub_subString.startsWith("6") || sub_subString.startsWith("7") || sub_subString.startsWith("8")
							|| sub_subString.startsWith("9"))){
					}
					else{
						System.out.println(sub_subString);
						parseredLine = sub_subString;
					}
				}
			}
			//第三次抽取
			int A = sub_subString.indexOf('<');
			int B = sub_subString.indexOf('>');
			int C = sub_subString.lastIndexOf('<');
			//如果A<0,说明没有HTML标签了;
			if(A < 0){
				//System.out.println("");
			}
			//如果A>0,说明还有HTML标签,此时需要判断是只有一个,还是有多个;
			else{
				//如果A = C,说明,只有一个HTML标签,此时还有三种情况,HTML标签在首,HTML标签居中,HTML标签在尾;
				if(A == C && A == 0){
					sub_sub_subString = sub_subString.substring(B+1, sub_subString.length());
					System.out.println(sub_sub_subString);
					parseredLine = sub_sub_subString;
				}
				else if(A == C && (B == sub_subString.length() - 1)){
					sub_sub_subString = sub_subString.substring(0, A);
					System.out.println(sub_sub_subString);
					parseredLine = sub_sub_subString;
				}
				else if(A == C && A != 0 && (B != sub_subString.length() - 1 )){
					//如果HTML标签居中,我们这时需要根据java的语法来判断,
					//此时还需要判断,我们需要抽取的内容在哪边,这时我们根据HTML标签内,有没有/来判断
					//如果书写规范的话,没有/,则我们需要抽取的内容在后边;否则在前边;
					//这种情况下,还要进行第四次抽取的判断;
						
					//如果开头是数字,可以判断我们需要抽取的代码在尾部
					if(sub_subString.substring(0, 1).matches("^[0-9]")){
						sub_sub_subString = sub_subString.substring(B+1,sub_subString.length());
						System.out.println(sub_sub_subString);
						parseredLine = sub_sub_subString;
					}
					else{
						sub_sub_subString = sub_subString.substring(0, A);
						System.out.println(sub_sub_subString);
						parseredLine = sub_sub_subString;
					}
				}
			}
		}
		return parseredLine;
	}
}

关键代码五: /JavaSpider_2016/src/com/spider/java/JavaSpider_1_5_URLParser.java  HTML网址抽取工具类

package com.spider.java;

public class JavaSpider_1_5_URLParser {
	
	/**
	 * 实现方法:
	 * 
     * 1,直接获取第一个A标签的起始位置,然后截取想要的属性,或者A标签; 
     * 2,然后从剩下的二级子串中,重复进行第一步的操作;
     * 3,以此类推,我们就可以获取所有的A标签了...
     * 
	 * 此方法需要接收以下几个参数:
	 * 1,当前页面的网址current_url,String类型;
	 * 2,当前需要处理的行line,String类型;
	 */
	public String parserURL(String line,String current_url){

	    //目标网址前缀  target_url_prefix
	    String target_url_prefix = "";
	    
	    //目标网址
	    String target_url = "";
	    
	    //目标网址后缀
	    String target_url_suffix = "";
	    
		/*
		 * 第一次抽取
		 */
	    
	    //定义一个int变量,用来表示第一个 A 标签起始位置的索引
	    int a_start = -100;
	    
	    //定义一个int变量,用来表示第一个 A 标签的 href 属性起始位置的索引
	    int href_start = -100;
	    
	    //定义一个int变量,用来表示第一个 A 标签的  第一个双引号 起始位置的索引
	    int double_start = -100;
		
		//定义一个String类型的变量,用来表示截取的子串,我们称之为一级子串
		String sub_String = "";
		
		//定义一个String类型的变量,用来表示截取的子串的子串,我们称之为二级子串
		String sub_sub_String = "";
		
		/*
		 * 首先对当前网址current_url进行处理,获得目标网址前缀
		 */
		int current_url_index = current_url.lastIndexOf("/");
		target_url_prefix = current_url.substring(0, current_url_index+1);
		
		//测试输出
		//System.out.println("当前输入的URL ==== " + current_url);
		//System.out.println("目标网址前缀 target_url_prefix ==== " + target_url_prefix);
		
		//获取第一个A标签的索引
		if(line.contains("<a")){
			
			a_start = line.indexOf("<a");
			sub_String = line.substring(a_start);
			
			//测试输出
			System.out.println("一级子串  sub_String = " + sub_String);
			
			href_start = sub_String.indexOf("href=");
			sub_sub_String = sub_String.substring(href_start+6);
			
			//测试输出
			System.out.println("二级子串  sub_sub_String = " + sub_sub_String);
			
			//如果二级子串非法,也就是href的第一位不是字母
			if(sub_sub_String.startsWith("?") || sub_sub_String.startsWith("/")){
				
				//测试输出
				System.out.println("非法网址,不保存!");
			}
			else{
				
				double_start = sub_sub_String.indexOf("\"");
				target_url_suffix = sub_sub_String.substring(0, double_start);
				
				//测试输出
				System.out.println("目标网址后缀  target_url_suffix = " + target_url_suffix);
			}
		}
		
		//如果目标网址后缀  target_url_suffix 不为空
		if(!"".equals(target_url_suffix)){
			
		    //目标网址为
		    target_url = target_url_prefix + target_url_suffix;
		    
		    //测试输出
		    //System.out.println("当前获得的目标网址为 target_url:" + target_url);
		
		}
		
		//返回目标网址
		return target_url;
	}
}

其他代码,可以在我的资源里面下载 :http://download.csdn.net/detail/reggergdsg/9406609


稍后继续更新爬虫1.6 


你可能感兴趣的:(servlet,javaweb开发,网页爬虫,javaspider)