Java SE之网络爬虫①

一 需求描述

  给一个url,将该url对应网页内的所有的链接查找出来,并补充完整为绝对路径

 简易版

/**
 * 
 * @author Zen Johnny
 * @date 2018年4月29日 下午11:19:01
 *
 */
package spider;

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * java实现爬虫
 */
public class Robot {
	public static List<String> captureWebLinks(String url){
		List<String> links = new LinkedList<String>();
		URL _url = null;
        URLConnection urlconn = null;
        BufferedReader br = null;
//        PrintWriter pw = null;
//        String regex = "http://[\\w+\\.?/?]+\\.[A-Za-z]+";
        String regex = "http[s]*://[\\w+\\.?/?]+\\.[A-Za-z]+";//url匹配规则
        Pattern p = Pattern.compile(regex);
        try {
        	_url = new URL(url);
            urlconn = _url.openConnection();
//          pw = new PrintWriter(new FileWriter("C:\Users\Zen Johnny\Desktop\robots.txt"), true);
            br = new BufferedReader(new InputStreamReader(
                    urlconn.getInputStream()));
            String buf = null;
            while ((buf = br.readLine()) != null) {
                Matcher buf_m = p.matcher(buf);
                while (buf_m.find()) {
//                    pw.println(buf_m.group());
                	links.add(buf_m.group());
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
//            pw.close();
        }
        return links;
	}
	
	public static void main(String[] args) {
		String url = "http://www.xhu.edu.cn/";
		List<String> links = captureWebLinks(url);
		for(String item:links)
			System.out.println(item);
		System.out.println("capture success");
    }
}

 output:

http://xiaoyou.xhu.edu.cn
http://oa.xhu.edu.cn
http://jwc.xhu.edu.cn
http://mail.xhu.edu.cn
http://urp.xhu.edu.cn
http://www.lib.xhu.edu.cn
http://english.xhu.edu.cn/main.htm
http://www.xhu.edu.cn/197/list.htm
http://xhjwc.xhu.edu.cn
http://yjs.xhu.edu.cn
http://yyjs.xhu.edu.cn
http://jxjy.xhu.edu.cn
http://fgc.xhu.edu.cn/xkpt/list.htm
http://qk.xhu.edu.cn
http://zb.xhu.edu.cn
http://yjs.xhu.edu.cn/zsgz/list.htm
http://jxjy.xhu.edu.cn/2647/list.htm
http://jy.xhu.edu.cn
http://oice.xhu.edu.cn
http://oice.xhu.edu.cn
http://dfhz.xhu.edu.cn
http://kjy.xhu.edu.cn
http://global.xhu.edu.cn
http://nmc.xhu.edu.cn
http://xhuasset.xhu.edu.cn/2312/list.htm
http://zgs.xhu.edu.cn
http://www.xhu.edu.cn/197/list.htm
http://xhjwc.xhu.edu.cn
http://yjs.xhu.edu.cn
http://yyjs.xhu.edu.cn
http://jxjy.xhu.edu.cn
http://fgc.xhu.edu.cn/xkpt/list.htm
http://qk.xhu.edu.cn
http://zb.xhu.edu.cn
http://yjs.xhu.edu.cn/zsgz/list.htm
http://jxjy.xhu.edu.cn/2647/list.htm
http://jy.xhu.edu.cn
http://oice.xhu.edu.cn
http://oice.xhu.edu.cn
http://dfhz.xhu.edu.cn
http://kjy.xhu.edu.cn
http://global.xhu.edu.cn
http://nmc.xhu.edu.cn
http://xhuasset.xhu.edu.cn/2312/list.htm
http://zgs.xhu.edu.cn
http://news.xhu.edu.cn/56/list.htm
http://news.xhu.edu.cn
http://news.xhu.edu.cn/b4/a6/c56a111782/page.htm
http://news.xhu.edu.cn/b4/a6/c56a111782/page.htm
http://news.xhu.edu.cn/b5/05/c56a111877/page.htm
http://news.xhu.edu.cn/b4/d2/c56a111826/page.htm
http://news.xhu.edu.cn/b4/a7/c56a111783/page.htm
http://news.xhu.edu.cn/b4/a6/c56a111782/page.htm
http://news.xhu.edu.cn/b4/73/c56a111731/page.htm
http://news.xhu.edu.cn/b4/75/c56a111733/page.htm
http://www.xhu.edu.cn/16/list.htm
http://www.xhu.edu.cn/16/list.htm
http://www.xhu.edu.cn/18/list.htm
http://www.xhu.edu.cn/19/list.htm
http://www.xhu.edu.cn/mtxh/list.htm
http://www.xhu.edu.cn/mtxh/list.htm
http://www.xhu.edu.cn/20/list.htm
http://www.xhu.edu.cn/xhsp/list.htm
http://www.xhu.edu.cn/23/list.htm
http://xxgk.xhu.edu.cn
http://lxyz.zt.xhu.edu.cn
http://xx19.xhu.edu.cn
http://xhu.yiban.cn
http://www.xhu.edu.cn/23/list.htm
http://xxgk.xhu.edu.cn
http://lxyz.zt.xhu.edu.cn
http://xx19.xhu.edu.cn
http://xhu.yiban.cn
http://oa.xhu.edu.cn
http://www.lib.xhu.edu.cn
http://kczx.xhu.edu.cn
http://jwc.xhu.edu.cn
http://urp.xhu.edu.cn
http://rsc.xhu.edu.cn/1410/list.htm
http://202.115.144.153/_web/_platform/teacherHome/web/login.jsp
https://www.gpticket.org
http://weibo.com
http://mp.weixin.qq.com
http://xhu.yiban.cn
http://www.beian.gov.cn
http://dcs.conac.cn/js/23/000/0000/60072077/CA230000000600720770001.js
capture success

 

二 程序方法清单

 

//捕获网页文本内容
String captureWebPageContent(String)

//在网页文本中检索并返回其所有链接
List<String> findLinks(String, String)

//将URL路径转为路径链表
List<String> dirs(String)

//将相对路径恢复为绝对路径
String revertToAbsolutePath(String, String)

 

三 程序实现

/**
 * 
 * @author Zen Johnny
 * @date 2018年4月29日 下午7:22:44
 *
 */
package spider;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WebPageSpider {
	private static Pattern pattern = null;
	private static Matcher matcher = null;
	private static BufferedReader br = null;
	private static StringBuffer text = null;
	private static URL _url = null;
	private static List<String> links = null;
	
	public static String captureWebPageContent(String url) throws UnsupportedEncodingException, IOException {
		text = new StringBuffer();
		_url = new URL(url);
		br = new BufferedReader(new InputStreamReader(_url.openStream(), "utf-8"));
		String line = null;
		while( (line = br.readLine()) != null) {
			text.append(line);
		}
		return text.toString();
	}
	
	/*
	 	在网页文本中检索并返回其所有链接
	 	@param refUrl:参照的绝对路径
	 	Eg:refAbsoluteUrl -> xxxx.com/X/Y/M/L/test.html?key=35435
	 */
	public static List<String> findLinks(String text, String refAbsoluteUrl) throws MalformedURLException {
		links = new LinkedList<String>();
		String regex = "((href)|(src)){1}=([\"\'])(.*?)\\4";//\\4:若前面是双(单)引号,则结束的时候也必须是双(单)引号
		pattern = Pattern.compile(regex);
		matcher = pattern.matcher(text);
		String link = null;
		while(matcher.find()) {
			link = matcher.group().replaceAll("((href=)|(src=)[\"\'])|([\'\"])", "");
			if(link.startsWith(".")) {//如果以相对路径开头,则为其默认添加基URL
				links.add(revertToAbsolutePath(refAbsoluteUrl, link));
			} else if(link.startsWith("/")){//以根路径作为开头
				URL tmp_url = new URL(refAbsoluteUrl);
				links.add(tmp_url.getHost() + link);
			} else if(link.endsWith("#")){//以#作为路径,即 当前路径(参照路径)
				links.add(refAbsoluteUrl);
			} else {
				links.add(link);
			}
			
		}
		return links;
	}
	
	/*
	 	将URL路径转为路径链表
	 	Eg:xxxx.com/X/Y/M/L/test.html?key=35435 => xxxx.com X Y M L test.html?key=35435
	 */
	public static List<String> dirs(String url) {
		java.util.List<String> dirs = new LinkedList<String>();
		String [] dirsArray = url.split("/+");
		for(String item : dirsArray) {
//			System.out.println(item);//test
			dirs.add(item.trim());
		}
		return dirs;
	}
	
	/*
	 	将相对路径恢复为绝对路径
	 	@param:curAbsoluteUrl	参照的绝对路径
	 	@param:relativeSubUrl	相对子路径
	 	
	 	xxxx.com/X/Y/M/L/test.html?key=35435	/hr/ry/ry			=> 	xxxx.com/X/Y/M/L/hr/ry/ry
	 	xxxx.com/X/Y/M/L/						./../../G/J/d.x		=>	xxxx.com/X/Y/G/J/d.x		
	 */
	public static String revertToAbsolutePath(String refAbsoluteUrl, String relativeSubUrl) {
		List<String> refPaths = dirs(refAbsoluteUrl);//参照路径链表
		List<String> relativePaths = dirs(relativeSubUrl);//相对路径链表
		List<String> dirs = new LinkedList<String>();
		StringBuffer path = new StringBuffer();

		if(refPaths.get(refPaths.size() - 1).matches("(.)*[\\.\\?](.)*")) {//若参照路径的最后一项以文件或者query形式结尾,则删除最后一项
//			System.out.println(refPaths.get(dirs.size() - 1));//test
			refPaths.remove(refPaths.size() - 1);
		}
		
		for(String item : relativePaths) {
//			System.out.println("item:"+item);//test
			if(item.equals("..")) {//上一层路径,则:删除refPaths的最后一项
				refPaths.remove(refPaths.size() - 1);
			} else if(!item.equals(".")) {//不为当前路径.或者空路径,即:实实在在的路径 
				if(!item.equals("")) {
					refPaths.add(item);
				} else {
//					System.out.println("【空】");//test
				}
			}
		}
		for(int item = 0,size = refPaths.size();item<size;item++) {//test
			path.append(refPaths.get(item) + (item+1 == size?"":"/"));
		}
		return path.toString();
	}
}

  

四 测试

 

package test;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.List;

import org.junit.Test;

import spider.WebPageSpider;

/**
 * 
 * @author Zen Johnny
 * @date 2018年4月29日 下午7:45:21
 *
 */

public class WebPageSpiderTest {
//	@Test
	public void captureWebPageContent() throws UnsupportedEncodingException, IOException {	
		String url = "http://www.xhu.edu.cn";
		System.out.println(WebPageSpider.captureWebPageContent(url));
	}
	
	@Test
	public void findLinks() throws UnsupportedEncodingException, IOException {	
		String urlString = "http://www.xhu.edu.cn/rcpy/list.htm";
		URL url = new URL(urlString);
		System.out.println("【Origin Url:" + url.toString() + "】");//test:http://www.xhu.edu.cn/rcpy/list.htm
		List<String> links = WebPageSpider.findLinks(WebPageSpider.captureWebPageContent(url.toString()),url.toString());
		for(String item:links) {
			System.out.println(item);
		}
	}
	
//	@Test
	public void revertToAbsolutePath() {
		String refAbsoluteUrl = "xxxx.com/X/Y/M/L/test.html?key=35435";
		String relativeSubUrl = "/hr/uy/rk/3535";
		System.out.println(WebPageSpider.revertToAbsolutePath(refAbsoluteUrl, relativeSubUrl));
	}
	
	public static void main(String[] args) throws UnsupportedEncodingException, IOException {
//		findLinks();
	}
}

 

output:

【Origin Url:http://www.xhu.edu.cn/rcpy/list.htm】
www.xhu.edu.cn/_css/_system/system.css
www.xhu.edu.cn/_upload/site/1/style/1/1.css
www.xhu.edu.cn/_upload/site/00/03/3/style/4/4.css
www.xhu.edu.cn/_js/_portletPlugs/simpleNews/css/simplenews.css
www.xhu.edu.cn/_js/_portletPlugs/datepicker/css/datepicker.css
www.xhu.edu.cn/_js/_portletPlugs/sudyNavi/css/sudyNav.css
www.xhu.edu.cn/_js/jquery.min.js
www.xhu.edu.cn/_js/jquery.sudy.wp.visitcount.js
www.xhu.edu.cn/_js/_portletPlugs/datepicker/js/jquery.datepicker.js
www.xhu.edu.cn/_js/_portletPlugs/datepicker/js/datepicker_lang_HK.js
www.xhu.edu.cn/_js/_portletPlugs/sudyNavi/jquery.sudyNav.js
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/css/base.css
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/css/media.css
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/images/ico.ico
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/extends/extends.js
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/js/window.js
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/extends/libs/html5.js
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/css/ie.css
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/extends/libs/pngfix.js
www.xhu.edu.cn/161/list.htm
www.xhu.edu.cn/162/list.htm
http://xiaoyou.xhu.edu.cn/
www.xhu.edu.cn/164/list.htm
www.xhu.edu.cn/163/list.htm
www.xhu.edu.cn/165/list.htm
javascript:void(0)
http://oa.xhu.edu.cn
http://jwc.xhu.edu.cn/
http://mail.xhu.edu.cn/
http://urp.xhu.edu.cn
http://www.lib.xhu.edu.cn/
http://english.xhu.edu.cn/main.htm
www.xhu.edu.cn/main.htm
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/images/logo.png
www.xhu.edu.cn/xxgk/list.htm
www.xhu.edu.cn/24/list.htm
www.xhu.edu.cn/25/list.htm
www.xhu.edu.cn/26/list.htm
www.xhu.edu.cn/60/list.htm
www.xhu.edu.cn/61/list.htm
http://www.xhu.edu.cn/197/list.htm
www.xhu.edu.cn/197/list.htm
www.xhu.edu.cn/198/list.htm
www.xhu.edu.cn/yjy/list.htm
www.xhu.edu.cn/rcpy/list.htm
www.xhu.edu.cn/122/list.htm
http://xhjwc.xhu.edu.cn/
http://yjs.xhu.edu.cn/
www.xhu.edu.cn/125/list.htm
http://yyjs.xhu.edu.cn/
http://jxjy.xhu.edu.cn/
www.xhu.edu.cn/12/list.htm
www.xhu.edu.cn/28/list.htm
www.xhu.edu.cn/30/list.htm
http://fgc.xhu.edu.cn/xkpt/list.htm
http://qk.xhu.edu.cn/
www.xhu.edu.cn/kydw/list.htm
http://www.xhu.edu.cn/rcpy/list.htm
http://zb.xhu.edu.cn/
http://yjs.xhu.edu.cn/zsgz/list.htm
http://jxjy.xhu.edu.cn/2647/list.htm
http://jy.xhu.edu.cn/
http://oice.xhu.edu.cn/
http://oice.xhu.edu.cn/
http://dfhz.xhu.edu.cn
http://kjy.xhu.edu.cn/
http://global.xhu.edu.cn/
www.xhu.edu.cn/15/list.htm
www.xhu.edu.cn/147/list.htm
http://nmc.xhu.edu.cn/
http://xhuasset.xhu.edu.cn/2312/list.htm
http://zgs.xhu.edu.cn/
www.xhu.edu.cn/bgdh/list.htm
www.xhu.edu.cn/xxgk/list.htm
www.xhu.edu.cn/24/list.htm
www.xhu.edu.cn/25/list.htm
www.xhu.edu.cn/26/list.htm
www.xhu.edu.cn/60/list.htm
www.xhu.edu.cn/61/list.htm
http://www.xhu.edu.cn/197/list.htm
www.xhu.edu.cn/197/list.htm
www.xhu.edu.cn/198/list.htm
www.xhu.edu.cn/yjy/list.htm
www.xhu.edu.cn/rcpy/list.htm
www.xhu.edu.cn/122/list.htm
http://xhjwc.xhu.edu.cn/
http://yjs.xhu.edu.cn/
www.xhu.edu.cn/125/list.htm
http://yyjs.xhu.edu.cn/
http://jxjy.xhu.edu.cn/
www.xhu.edu.cn/12/list.htm
www.xhu.edu.cn/28/list.htm
www.xhu.edu.cn/30/list.htm
http://fgc.xhu.edu.cn/xkpt/list.htm
http://qk.xhu.edu.cn/
www.xhu.edu.cn/kydw/list.htm
http://www.xhu.edu.cn/rcpy/list.htm
http://zb.xhu.edu.cn/
http://yjs.xhu.edu.cn/zsgz/list.htm
http://jxjy.xhu.edu.cn/2647/list.htm
http://jy.xhu.edu.cn/
http://oice.xhu.edu.cn/
http://oice.xhu.edu.cn/
http://dfhz.xhu.edu.cn
http://kjy.xhu.edu.cn/
http://global.xhu.edu.cn/
www.xhu.edu.cn/15/list.htm
www.xhu.edu.cn/147/list.htm
http://nmc.xhu.edu.cn/
http://xhuasset.xhu.edu.cn/2312/list.htm
http://zgs.xhu.edu.cn/
www.xhu.edu.cn/bgdh/list.htm
www.xhu.edu.cn/rczp/list.htm
www.xhu.edu.cn/_upload/column/00/79/121/picture.jpg
www.xhu.edu.cn/122/list.htm
http://xhjwc.xhu.edu.cn/
http://yjs.xhu.edu.cn/
www.xhu.edu.cn/125/list.htm
http://yyjs.xhu.edu.cn/
http://jxjy.xhu.edu.cn/
www.xhu.edu.cn/main.htm
www.xhu.edu.cn/rcpy/list.htm
www.xhu.edu.cn/122/list.htm
http://oa.xhu.edu.cn
http://www.lib.xhu.edu.cn/
http://kczx.xhu.edu.cn/
http://jwc.xhu.edu.cn/
http://urp.xhu.edu.cn
http://rsc.xhu.edu.cn/1410/list.htm
http://202.115.144.150/
http://202.115.144.153/_web/_platform/teacherHome/web/login.jsp
http://weibo.com/p/1002061729488283/home?from=page_100206&mod=TAB&is_all=1#place
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/images/weiibo.jpg
http://mp.weixin.qq.com/profile?src=3&timestamp=1463020630&ver=1&signature=IoHgaEnITl0-zOyyrLrEP5mwFoQAfa0U8EOiHghtGIY4im9vnwvNNBLECI5CPdrdfWSDyd0JNBIZBU*j*EOgWA== ;
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/images/weixin.jpg
http://xhu.yiban.cn/
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/images/yiban.png
javascript:SendMailTo(db@mail.xhu.edu.cn)
javascript:SendMailTo(xiaoban@mail.xhu.edu.cn)
www.xhu.edu.cn/190/list.htm
www.xhu.edu.cn/191/list.htm
javascript:;
http://dcs.conac.cn/js/23/000/0000/60072077/CA230000000600720770001.js
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/js/app.js
www.xhu.edu.cn/_upload/tpl/00/06/6/template6/js/comcus.js
www.xhu.edu.cn/_visitcount?siteId=3&type=2&columnId=121

 

五 缺陷

  目前,只能支持网页字符集编码为JDK所支持的几大类型:ISO8859-1、UTF-8等,不支持GB2312和GBK

 

 六 参考文档

 使用Java实现网络爬虫:https://www.cnblogs.com/qianzf/p/6796588.html

posted @ 2018-04-29 22:05  千千寰宇  阅读(407)  评论(0编辑  收藏  举报