/*
* * JavaSpier的目标:*
* 1,我们要获取的是
* http://commons.apache.org/proper/commons-fileupload/apidocs/src-html/org/apache/commons/
* Apache org.apache.commons站点下的所有源代码文件,也就是最终的.html文件。
*,2,我们要对获取到的源代码网页,进行格式化处理,以java源代码的方式,保存到指定文件中。
* 3,每个.html页面保存到对应的.java文件中。这些文件都保存到电脑的指定目录下。
*
* JavaSpier 1.3版本 我们实现了以下功能:
* 1,自动检索当前网址所在网页的HTML内容,并从中抽取所有的URL地址,然后保存到数据库中;
* 2,需要说明的是,这里保存的网址,有的是.html结尾的,有的是一个目录,比如.../fileupload/
* 3,在JavaSpier 1.3版本,我们并没有将网页内容保存到文件中,因为我们的目的是先获得所有的目标网址,然后统一处理;
*
*/
该系统,我们使用的servlet + MySQL5.5来实现的。
系统关键文件结构如下:
前台JSP页面:
/Spider/WebRoot/WEB-INF/spider/GetAllUrl_JavaSpider_1_3.jsp
/Spider/WebRoot/WEB-INF/spider/Error.jsp
/Spider/WebRoot/WEB-INF/spider/Success.jsp
后台java文件:
/Spider/src/com/spider/dao/JavaSpider_1_3_Dao.java Dao层接口
/Spider/src/com/spider/dao/impl/JavaSpider_1_3_DaoImpl.java Dao层实现类
/Spider/src/com/spider/service/JavaSpider_1_3_Service.java Service层接口
/Spider/src/com/spider/service/impl/JavaSpider_1_3_ServiceImpl.java Service层实现类
/Spider/src/com/spider/servlet/GetAllUrl_JavaSpider_1_3_Servlet.java Servlet控制类
/Spider/src/com/spider/java/JavaSpiderBase_1_3.java 爬虫核心接口
/Spider/src/com/spider/java/JavaSpider_1_3.java 爬虫核心接口实现类
/Spider/src/com/spider/java/JavaSpider_1_3_URLParser.java 对网页中的链接进行处理的工具类,以行为单位,获取网页中的所有URL地址
/Spider/src/com/spider/java/JavaSpider_1_3_HTMLParser.java 对网页进行抽取的工具类,也就是去掉HTML标签,得到网页内容
配置文件:
/Spider/WebRoot/WEB-INF/web.xml
下面贴上所有文件的源代码,可能较多,大家耐心...
/Spider/WebRoot/WEB-INF/spider/GetAllUrl_JavaSpider_1_3.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>JavaSpider 抓取所有的目标网址,保存到数据库</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<div>
<form class="STYLE-NAME" action="GetAllUrl_JavaSpider_1_3_Servlet" method="post">
<label>
<span> JavaSpier 1.3版本</span>
</label><br>
<label>
<span> 我们进行了以下改进:</span>
</label><br>
<label>
<span> 1,从指定网页,抓取该网页中的所有的网址,保存到数据库</span>
</label><br>
<label>
<span> 2,需要说明的是,这里保存的网址,有的是.html结尾的,有的是一个目录,比如.../fileupload/</span>
</label><br>
<label>
<span> 3,比如下面这个网址,我们可以获取该网址下,所有的二级网址,并保存到数据库中...</span>
</label><br>
<label>
<span> http://commons.apache.org/proper/commons-fileupload/apidocs/src-html/org/apache/commons/fileupload/</span>
</label><br>
<label>
<span>后缀级别level:</span>
<input type="text" name="LEVEL">
</label><br>
<label>
<span>请输入网址:</span>
<input type="text" name="URL" id="">
</label><br>
<input type="submit" name="submit" id="" value="点击保存到数据库中">
</form>
</div>
</body>
</html>
/Spider/WebRoot/WEB-INF/spider/Error.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>程序出现异常</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<div>
<form class="STYLE-NAME" action="">
<label>
<span> 程序出现异常</span>
</label><br>
<label>
<span> </span>
</label><br>
</form>
</div>
</html>
/Spider/WebRoot/WEB-INF/spider/Success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>文件保存成功</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<div>
<form class="STYLE-NAME" action="">
<label>
<span> 如果文件保存成功,则跳转到这个页面</span>
</label><br>
<label>
<span> </span>
</label><br>
</form>
</div>
<!-- 显示服务器端传递过来的提示信息message -->
<div>
<c:if test=""></c:if>
<c:out value="${request.message}"></c:out>
<label><span> A ${message}</span></label>
</div>
</html>
后台java文件:
/Spider/src/com/spider/dao/JavaSpider_1_3_Dao.java Dao层接口
package com.spider.dao;
import java.util.Map;
import com.spider.Model.Temp_url;
import com.spider.Model.Url;
public interface JavaSpider_1_3_Dao {
//增
public boolean saveToDatabase(Url url);
//增
public boolean saveToDatabase(Temp_url temp_url);
//查
public Map<Integer,String> getAllUrlsOfLevel(int level);
}
/Spider/src/com/spider/dao/impl/JavaSpider_1_3_DaoImpl.java Dao层实现类
ackage com.spider.dao.impl;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import com.spider.Model.Temp_url;
import com.spider.Model.Url;
import com.spider.dao.JavaSpider_1_3_Dao;
import com.spider.util.JavaSpider_JDBC;
public class JavaSpider_1_3_DaoImpl implements JavaSpider_1_3_Dao {
@Override
public boolean saveToDatabase(Temp_url temp_url) {
//创建数据库连接对象
JavaSpider_JDBC JavaSpider_JDBC = new JavaSpider_JDBC();
//定义一个Boolean类型的变量,用来表示数据库操作是否成功
boolean flag = false;
//用PreparedStatement
String sql = "insert into temp_url(id,url,level) values(null,?,?)";
try{
//调用dao层增加方法,把数据插入到数据库
JavaSpider_JDBC.javaSpider_JDBC(sql);
//执行数据库操作,如何执行预处理的SQL语句,请参考PreparedStatement源码,如下
JavaSpider_JDBC.pst.setString(1, temp_url.getTempurl());
JavaSpider_JDBC.pst.setInt(2, temp_url.getLevel());
JavaSpider_JDBC.pst.execute();
//测试输出
System.out.println("数据库插入成功...");
flag = true;
}
catch(Exception e){
//测试输出
System.out.println("数据库插入异常...");
e.printStackTrace();
}
return flag;
}
@Override
public boolean saveToDatabase(Url url) {
//创建数据库连接对象
JavaSpider_JDBC JavaSpider_JDBC = new JavaSpider_JDBC();
//定义一个Boolean类型的变量,用来表示数据库操作是否成功
boolean flag = false;
//用PreparedStatement
String sql = "insert into url(id,url,date) values(null,?,?)";
try{
//调用dao层增加方法,把数据插入到数据库
JavaSpider_JDBC.javaSpider_JDBC(sql);
//执行数据库操作,如何执行预处理的SQL语句,请参考PreparedStatement源码,如下
JavaSpider_JDBC.pst.setString(1, url.getUrl());
JavaSpider_JDBC.pst.setString(2, url.getDate());
JavaSpider_JDBC.pst.execute();
//测试输出
System.out.println("数据库插入成功...");
flag = true;
}
catch(Exception e){
//测试输出
System.out.println("数据库插入异常...");
e.printStackTrace();
}
return flag;
}
@Override
public Map<Integer, String> getAllUrlsOfLevel(int level) {
//创建数据库连接对象
JavaSpider_JDBC JavaSpider_JDBC = new JavaSpider_JDBC();
//查询结果集
ResultSet resultSet;
//Map<Integer, String>
Map<Integer, String> urls = new HashMap<Integer, String>();
//用PreparedStatement
String sql = "select url from temp_url where level=?";
try{
//调用dao层增加方法,把数据插入到数据库
JavaSpider_JDBC.javaSpider_JDBC(sql);
//执行数据库操作,如何执行预处理的SQL语句,请参考PreparedStatement源码,如下
JavaSpider_JDBC.pst.setInt(1, level);
resultSet = JavaSpider_JDBC.pst.executeQuery();
//把查询结果保存到Map中
int i = 1;
while(resultSet.next()){
urls.put(i-1, resultSet.getString("url"));
System.out.println("dao测试:" + urls.get(i-1));
i++;
}
//测试输出
System.out.println("数据库插入成功...");
}
catch(Exception e){
//测试输出
System.out.println("数据库插入异常...");
e.printStackTrace();
}
return urls;
}
}
/Spider/src/com/spider/service/JavaSpider_1_3_Service.java Service层接口
package com.spider.service;
import java.util.Map;
import com.spider.Model.Temp_url;
import com.spider.Model.Url;
public interface JavaSpider_1_3_Service {
//增
public boolean saveToDatabase(Url url);
//增
public boolean saveToDatabase(Temp_url temp_url);
//查
public Map<Integer,String> getAllUrlsOfLevel(int level);
}
/Spider/src/com/spider/service/impl/JavaSpider_1_3_ServiceImpl.java Service层实现类
package com.spider.service.impl;
import java.util.HashMap;
import java.util.Map;
import com.spider.Model.Temp_url;
import com.spider.Model.Url;
import com.spider.dao.JavaSpider_1_3_Dao;
import com.spider.dao.impl.JavaSpider_1_3_DaoImpl;
import com.spider.service.JavaSpider_1_3_Service;
public class JavaSpider_1_3_ServiceImpl implements JavaSpider_1_3_Service {
//定义Dao层接口对象
JavaSpider_1_3_Dao javaSpider_1_3_Dao = new JavaSpider_1_3_DaoImpl();
public JavaSpider_1_3_Dao getJavaSpider_1_3_Dao() {
return javaSpider_1_3_Dao;
}
public void setJavaSpider_1_3_Dao(JavaSpider_1_3_Dao javaSpider_1_3_Dao) {
this.javaSpider_1_3_Dao = javaSpider_1_3_Dao;
}
@Override
public boolean saveToDatabase(Temp_url temp_url) {
//定义一个Boolean类型的变量,用来表示数据库操作是否成功
boolean flag = false;
//
flag = javaSpider_1_3_Dao.saveToDatabase(temp_url);
return flag;
}
@Override
public boolean saveToDatabase(Url url) {
//定义一个Boolean类型的变量,用来表示数据库操作是否成功
boolean flag = false;
//
flag = javaSpider_1_3_Dao.saveToDatabase(url);
return flag;
}
@Override
public Map<Integer, String> getAllUrlsOfLevel(int level) {
Map<Integer, String> urls = new HashMap<Integer, String>();
urls = javaSpider_1_3_Dao.getAllUrlsOfLevel(level);
return urls;
}
}
/Spider/src/com/spider/servlet/GetAllUrl_JavaSpider_1_3_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.Temp_url;
import com.spider.java.JavaSpider_1_3;
import com.spider.service.JavaSpider_1_3_Service;
import com.spider.service.impl.JavaSpider_1_3_ServiceImpl;
@SuppressWarnings("serial")
public class GetAllUrl_JavaSpider_1_3_Servlet extends HttpServlet{
//定义service层接口对象
JavaSpider_1_3_Service javaSpider_1_3_Service = new JavaSpider_1_3_ServiceImpl();
//setter、getter方法
public JavaSpider_1_3_Service getJavaSpider_1_3_Service() {
return javaSpider_1_3_Service;
}
public void setJavaSpider_1_3_Service(JavaSpider_1_3_Service javaSpider_1_3_Service) {
this.javaSpider_1_3_Service = javaSpider_1_3_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 = "";
//生成url对象
Temp_url url_temp = new Temp_url();
//定义一个Map,用来封装所有的URL网址
Map<Integer,String> urls = new HashMap<Integer,String>();
//
Map<Integer,String> urls_rs = new HashMap<Integer,String>();
//定义一个Map,用来封装所有的url对象
Map<Integer,Temp_url> url_entity = new HashMap<Integer,Temp_url>();
//生成JavaSpider_1_3_URLParser对象
JavaSpider_1_3 javaSpider_1_3 = new JavaSpider_1_3();
//生成日期对象
Date current_date = new Date();
//设置日期格式化样式为:yyyy-MM-dd
SimpleDateFormat SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//格式化当前日期
SimpleDateFormat.format(current_date.getTime());
//url.setUrl(URL);
//url.setDate(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_3.getFormatCode_1_3(URL);
//封装url实体
for(int i=0;i<urls.size();i++){
url_temp.setTempurl(urls.get(i));
url_temp.setLevel(LEVEL);
url_entity.put(i, url_temp);
//调用业务逻辑处理对象,完成数据保存到数据库的业务逻辑
javaSpider_1_3_Service.saveToDatabase(url_entity.get(i));
}
//调用业务逻辑处理对象,完成数据保存到数据库的业务逻辑
//for(int j=0;j<url_entity.size();j++){
//javaSpider_1_3_Service.saveToDatabase(url_entity.get(j));
//}
message = "文件保存完成...";
//把信息保存到request请求域中,传递到客户端
request.setAttribute("message", message);
//跳转到SpiderIndex.jsp页面
request.getRequestDispatcher("WEB-INF/spider/Success.jsp").forward(request, response);
}
else{
urls_rs = javaSpider_1_3_Service.getAllUrlsOfLevel(LEVEL);
//封装url实体
for(int i=0;i<urls_rs.size();i++){
//url_temp.setTempurl(urls_rs.get(i));
//url_temp.setLevel(LEVEL);
//url_entity.put(i, url_temp);
urls = javaSpider_1_3.getFormatCode_1_3(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++){
url_temp.setTempurl(urls.get(j));
url_temp.setLevel(LEVEL);
url_entity.put(j, url_temp);
//测试输出
System.out.println("新抓取的网址 = " + urls.get(j));
javaSpider_1_3_Service.saveToDatabase(url_entity.get(j));
}
}
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");
}
}
/Spider/src/com/spider/java/JavaSpiderBase_1_3.java 爬虫核心接口
package com.spider.java;
import java.io.IOException;
import java.util.Map;
import org.apache.http.client.ClientProtocolException;
public interface JavaSpiderBase_1_3 {
//带参数的方法 JavaSpider_1_3版本
public Map<Integer,String> getFormatCode_1_3(String URL) throws ClientProtocolException, IOException;
}
/Spider/src/com/spider/java/JavaSpider_1_3.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;
/*
* JavaSpier 1.3版本 之 网页内容处理类public class JavaSpider_1_3
* 我们进行了以下改进:
* 1,增加自动搜索目标网页的功能,先实现把一个站点下的网址都保存起来的功能。
* 2,把一个站点下的网址,都保存到数据库中;
*
* 在网页内容处理类public class JavaSpider_1_3,我们主要进行网页的爬取和文件IO的业务逻辑;
* 网页抽取的操作从这个类中剥离;
*/
@SuppressWarnings("deprecation")
public class JavaSpider_1_3 implements JavaSpiderBase_1_3{
//定义一个String变量,用来表示新生成的文件的存放路径
public static final String FILE_PATH = "E:\\uploadFiles\\";
@Override
public Map<Integer,String> getFormatCode_1_3(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_3_URLParser对象
JavaSpider_1_3_URLParser javaSpider_1_3_URLParser = new JavaSpider_1_3_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_3_URLParser.parserURL_2(line, URL))){
//封装到数组中
urls.put(z, javaSpider_1_3_URLParser.parserURL_2(line, URL));
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_3_URLParser.parserURL_2(line, URL))){
//封装到数组中
urls.put(z, javaSpider_1_3_URLParser.parserURL_2(line, URL));
//System.out.println("在JavaSpider中测试输出获取到的所有网址:" + urls.get(z));
z++;
}
}
}
}
if(httpEntity != null){
//
httpEntity.consumeContent();
}
}
//返回Map
return urls;
}
}
/Spider/src/com/spider/java/JavaSpider_1_3_URLParser.java 对网页中的链接进行处理的工具类,以行为单位,获取网页中的所有URL地址
package com.spider.java;
/*
* * JavaSpier的目标:
*
* 1,我们要获取的是http://commons.apache.org/proper/commons-fileupload/apidocs/src-html/org/apache/commons/
* Apache org.apache.commons站点下的所有源代码文件,也就是最终的.html文件。
*,2,我们要对获取到的源代码网页,进行格式化处理,以java源代码的方式,保存到指定文件中。
* 3,每个.html页面保存到对应的.java文件中。这些文件都保存到电脑的指定目录下。
*
* JavaSpier 1.3版本 之 网页内容处理类public class JavaSpider_1_3_URLParser
* 我们进行了以下改进:
* 1,自动检索当前网址所在网页的HTML内容,并从中抽取所有的URL地址,然后保存到数据库中;
* 2,需要说明的是,这里保存的网址,有的是.html结尾的,有的是一个目录,比如.../fileupload/
* 3,在JavaSpier 1.3版本,我们并没有将网页内容保存到文件中,因为我们的目的是先获得所有的目标网址,然后统一处理;
*
* 在网页A标签处理类public class JavaSpider_1_3_URLParser,
* 我们对网页中的链接进行处理,返回目标网址;
*/
public class JavaSpider_1_3_URLParser {
/**
* 第二种实现方法:
*
* 1,直接获取第一个A标签的起始位置,然后截取想要的属性,或者A标签;
* 2,然后从剩下的二级子串中,重复进行第一步的操作;
* 3,以此类推,我们就可以获取所有的A标签了...
*
* 此方法需要接收以下几个参数:
* 1,当前页面的网址current_url,String类型;
* 2,当前需要处理的行line,String类型;
*/
public String parserURL_2(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;
}
}
/Spider/src/com/spider/java/JavaSpider_1_3_HTMLParser.java 对网页进行抽取的工具类,也就是去掉HTML标签,得到网页内容
package com.spider.java;
public class JavaSpider_1_3_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('>');
//int m = line.lastIndexOf('>');
//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;
}
}
/Spider/src/com/spider/Model/Temp_url.java 实体类
package com.spider.Model;
public class Temp_url {
/*
* 数据库名称:test
*
* 表名称:temp_url
* 字段1,id,主键,auto_increment;
* 字段2,url,varchar(200) not null
* 字段3,level,int(4),not null
*
* 建表语句:
create table temp_url(
id int auto_increment primary key,
url varchar(200) not null,
level int(4) not null
);
* 测试数据
* insert into url(id,url,date) values(null,"http://commons.apache.org/proper/commons-fileupload/apidocs/src-
html/org/apache/commons/fileupload/portlet/PortletFileUpload.html#line.51",now());
*
* url字段长度50不够用,我们把长度修改为100
* alter table url modify url varchar(200) not null;
*/
//id,主键,自增长
int id;
//临时URL,不是有效的URL
String tempurl;
//时间,date
int level;
//setter、getter方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTempurl() {
return tempurl;
}
public void setTempurl(String tempurl) {
this.tempurl = tempurl;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
}
配置文件:web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>JavaSpider</display-name>
<!-- 配置servlet 用于设置Servlet的注册名称和Servlet的完整类名-->
<!-- 抓取所有的目标网址,保存到数据库 -->
<servlet>
<servlet-name>GetAllUrl_JavaSpider_1_3_Servlet</servlet-name>
<servlet-class>com.spider.servlet.GetAllUrl_JavaSpider_1_3_Servlet</servlet-class>
</servlet>
<!-- 配置servlet-mapping 用于映射一个已注册的Servlet的一个对外访问路径-->
<!-- 注意:-->
<!-- 1,url-pattern是对外访问路径,对应JSP页面的action的值-->
<!-- 2,客户端发送的action请求,对应url-pattern斜杠后面的参数;-->
<!-- 3,action请求找到url-pattern以后,根据servlet-name去找对应的servlet类;-->
<!-- 4,servlet类接收到客户端的请求以后,开始处理请求;-->
<!-- 抓取所有的目标网址,保存到数据库 -->
<servlet-mapping>
<servlet-name>GetAllUrl_JavaSpider_1_3_Servlet</servlet-name>
<url-pattern>/GetAllUrl_JavaSpider_1_3_Servlet</url-pattern>
</servlet-mapping>
</web-app>
这是一个没有经过优化的,简单的爬虫,可以爬取指定站点的网页,并将链接保存到数据库中。后续还会更新更高版本...