分享一个简单的java爬虫框架

反复给网站编写不同的爬虫逻辑太麻烦了,自己实现了一个小框架

可以自定义的部分有:

请求方式(默认为Getuser-agent为谷歌浏览器的设置),可以通过实现RequestSet接口来自定义请求方式

储存方式(默认储存在f盘的html文件夹下),可以通过SaveUtil接口来自定义保存方式

需要保存的资源(默认为整个html页面)

筛选方式(默认所有url都符合要求),通过实现ResourseChooser接口来自定义需要保存的url和资源页面

实现的部分有:

html页面的下载方式,通过HttpClient实现html页面的下载

html页面的解析部分,通过jsoup实现html页面的解析

HtmlDownloader类,用于根据一个url下载一个html页面

package DownloadPackage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
/*
 * 根据一个url下载一个html页面
 */
public class HtmlDownloader {
	RequestSet requestset = null;
	public HtmlDownloader(RequestSet requestset){
		this.requestset = requestset;
	}
	public String downloadhtml(String url){
		String html = null;
		//创建一个客户端
		//创建一个读取流从entity读取html
		BufferedReader reader = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpResponse response = null;
		try {
			response = httpclient.execute(requestset.getMethod(url));
			HttpEntity entity = response.getEntity();
			reader = new BufferedReader(new InputStreamReader(entity.getContent()));
			StringBuilder sb = new StringBuilder();
			while((html = reader.readLine()) != null){
				sb.append(html);
			}
			html = sb.toString();
			System.out.println("一个html页面获取成功");
		}
		catch (IOException e) {
			System.out.println(url+"连接失败");
		}
		finally{
			if(reader != null){
				try {
					reader.close();
					httpclient.close();
				}
				catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return html;
	}
}

UrlGet类,用于根据一个html页面获得所有的url连接

package DownloadPackage;
import java.util.LinkedList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class UrlGet {
	public LinkedList<String> geturls(String html){
		LinkedList<String> urls = new LinkedList<String>();
		Document doc = Jsoup.parse(html);
		Elements links = doc.getElementsByTag("a");
		for (Element link:links){
			String url = link.attr("href");
			urls.add(url);
		}
		return urls;
	}
}

资源选择接口,需要实现三个方法,第一是isNeed方法,判断url是否为需要的,第二个是isResourse方法,判断url页面是不是需要的资源页面,第三个是process方法,

有时网页上的url是我们需要的但是格式不对,对url进行加工

package ChoosePackage;
public interface ResourseChooser {
	public Boolean isNeed(String url);
	public Boolean isResourse(String url);
	public String process(String url);
}

RequsetSet类,用于自定义请求方法的接口,实现getMethod方法获取请求方法

package DownloadPackage;
import org.apache.http.client.methods.HttpGet;
/*
 * 一个用于获得Request请求的接口
 * 实现getMethod方法获取Get方法
 */
public interface RequestSet {
	public HttpGet getMethod(String url);
}
Saveutil接口用于自定义保存方式,需要实现save方法
package SaveUtil;
/*
 * 数据储存的工具接口,必须实现保存方法
 */
public interface SaveUtil {
	public void save(String url,String html);
}

Spider类,有五中构造方法,可以实现多种自定义操作,其中实现了上述自定义接口的默认实现类

package Spider;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import ChoosePackage.MyResourseChooser;
import ChoosePackage.ResourseChooser;
import DownloadPackage.HtmlDownloader;
import DownloadPackage.RequestSet;
import DownloadPackage.UrlGet;
import SaveUtil.MySaveUtil;
import SaveUtil.SaveUtil;
/*
 * 用于爬取资源的类
 */
public class Spider{
	public static void main(String[] args) {
		new Spider("http://www.bilibili.net").spiderstart();
	}
	//种子url
	String seed = null;
	//用于保存数据的类,需要自己实现
	private SaveUtil saveutil = null;
	//html下载类
	private HtmlDownloader downloader = null;
	//url下载类
	private UrlGet urldownloader = null;
	//资源选择工具
	private ResourseChooser resoursechooser = null;
	//用于保存未下载的网页
	LinkedList<String> unvisited = new LinkedList<String>();
	//用于保存已下载的网页
	HashSet<String> visited = new HashSet<String>();
	//自定义储存方式,请求方式,资源筛选方式的构造方法
	public Spider(SaveUtil saveutil,RequestSet request,ResourseChooser resoursechooser,String seed){
		this.saveutil = saveutil;
		this.downloader = new HtmlDownloader(request);
		this.urldownloader = new UrlGet();
		this.resoursechooser = resoursechooser;
		this.seed = seed;
		unvisited.add(seed);
	}
	//自定义储存方式,资源筛选方式的构造方法
	public Spider(SaveUtil saveutil,ResourseChooser resoursechooser,String seed){
		this.resoursechooser = resoursechooser;
		this.downloader = new HtmlDownloader(new getRequest());
		this.saveutil = saveutil;
		this.urldownloader = new UrlGet();
		this.seed = seed;
		unvisited.add(seed);
	}
	//自定义储存方式,请求的构造方法
	public Spider(SaveUtil saveutil,RequestSet requestset,String seed){
		this.saveutil = saveutil;
		this.downloader = new HtmlDownloader(requestset);
		this.resoursechooser = new MyResourseChooser();
		this.urldownloader = new UrlGet();
		this.seed = seed;
		unvisited.add(seed);
	}
	//自定义储存方式的构造方法
	public Spider(SaveUtil saveutil,String seed){
		this.saveutil = saveutil;
		this.downloader = new HtmlDownloader(new getRequest());
		this.resoursechooser = (new MyResourseChooser());
		this.urldownloader = new UrlGet();
		this.seed = seed;
		unvisited.add(seed);
	}
	//默认的爬虫构造方法
	public Spider(String seed){
		this.saveutil = new MySaveUtil();
		this.downloader = new HtmlDownloader(new getRequest());
		this.resoursechooser = (new MyResourseChooser());
		this.urldownloader = new UrlGet();
		this.seed = seed;
		unvisited.add(seed);
	}
	//开始爬取的方法
	private void spiderstart(){
		String html = null;
		while(!unvisited.isEmpty()){
			String url = unvisited.poll();
			System.out.println("开始获取"+url);
			if(resoursechooser.isNeed(url)){
				try{
					html = downloader.downloadhtml(url);
				}
				catch(RuntimeException e){
					System.out.println(url+"连接获取失败");
					continue;
				}
				visited.add(url);
				LinkedList<String> urls = new LinkedList<String>();
				try{
					urls = urldownloader.geturls(html);
				}
				catch(RuntimeException e){
					System.out.println(url+"的html页面为空");
					continue;
				}
				Iterator<String> it = urls.iterator();
				while(it.hasNext()){
					String newurl = it.next();
					if(resoursechooser.isNeed(newurl)&&!visited.contains(newurl)&&!unvisited.contains(newurl)){
						newurl = resoursechooser.process(newurl);
						unvisited.add(newurl);
						System.out.println(newurl+"加入页面");
					}
				}
				System.out.println("获取了"+url+"上的所有url");
				if(resoursechooser.isResourse(url)){
					saveutil.save(url,html);
				}
			}
		}
	}
	//默认资源筛选类
	private class MyResourseChooser implements ResourseChooser{
		@Override
		public Boolean isNeed(String url) {
			// TODO Auto-generated method stub
			if(!url.startsWith("/")&&!url.startsWith("http")){
				return false;
			}
			return true;
		}
		@Override
		public Boolean isResourse(String url) {
			// TODO Auto-generated method stub
			return true;
		}
		@Override
		public String process(String url) {
			// TODO Auto-generated method stub
			if(!url.startsWith("http")){
				url = seed+url;
			}
			return url;
		}
	}
	public class getRequest implements RequestSet{
		public HttpGet getMethod(String url) {
			// TODO Auto-generated method stub
			//创建一个get请求方法
			HttpGet getmethod = new HttpGet(url);
			//HttpHost proxy = new HttpHost("124.88.67.81",80);这里不设置代理IP
			//设置请求超时时间等
			RequestConfig responseconfig = RequestConfig.custom().setConnectionRequestTimeout(10000).setConnectTimeout(10000).setSocketTimeout(10000).build();
			//设置请求头,主要是user-agent
			getmethod.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
			//设置请求参数
			getmethod.setConfig(responseconfig);
			return getmethod;
		}
	}
	//默认的存储类
	public class MySaveUtil implements SaveUtil{
		@Override
		public void save(String url, String html) {
			// TODO Auto-generated method stub
			String filename = getfilename(url);
			BufferedWriter writer = null;
			try{
				writer = new BufferedWriter(new FileWriter(filename));
				writer.write(html);
				writer.flush();
				System.out.println("文件写入成功");
			}
			catch(IOException e){
				System.out.println("文件写入失败");
			}
			finally{
				try {
					if(writer != null)
					writer.close();
				}
				catch (IOException e) {
					// TODO Auto-generated catch block
					System.out.println("流关闭失败");
				}
			}
		}
		private String getfilename(String url){
			String fileparentpath = "f://html";
			File file = new File(fileparentpath);
			if(!file.exists()){
				file.mkdir();
			}
			int last = url.lastIndexOf(".");
			int first = url.indexOf(".");
			url = url.substring(first,last);
			url = url.replaceAll("\\.", "");
			url = url.replaceAll("/", "");
			return fileparentpath+"/"+url+".txt";
		}
	}
}

总结

以上就是本文关于分享一个简单的java爬虫框架的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:Python爬虫实例爬取网站搞笑段子、Java线程之锁对象Lock-同步问题更完美的处理方式代码实例、Java编程几个循环实例代码分享等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对本站的支持!

(0)

相关推荐

  • Java实现爬虫给App提供数据(Jsoup 网络爬虫)

    一.需求 最近基于 Material Design 重构了自己的新闻 App,数据来源是个问题. 有前人分析了知乎日报.凤凰新闻等 API,根据相应的 URL 可以获取新闻的 JSON 数据.为了锻炼写代码能力,笔者打算爬虫新闻页面,自己获取数据构建 API. 二.效果图 下图是原网站的页面 爬虫获取了数据,展示到 APP 手机端 三.爬虫思路 关于App 的实现过程可以参看这几篇文章,本文主要讲解一下如何爬虫数据. Android下录制App操作生成Gif动态图的全过程 :http://www

  • 详解Java豆瓣电影爬虫——小爬虫成长记(附源码)

    以前也用过爬虫,比如使用nutch爬取指定种子,基于爬到的数据做搜索,还大致看过一些源码.当然,nutch对于爬虫考虑的是十分全面和细致的.每当看到屏幕上唰唰过去的爬取到的网页信息以及处理信息的时候,总感觉这很黑科技.正好这次借助梳理Spring MVC的机会,想自己弄个小爬虫,简单没关系,有些小bug也无所谓,我需要的只是一个能针对某个种子网站能爬取我想要的信息就可以了.有Exception就去解决,可能是一些API使用不当,也可能是遇到了http请求状态异常,又或是数据库读写有问题,就是在这

  • Java爬虫抓取视频网站下载链接

    本篇文章抓取目标网站的链接的基础上,进一步提高难度,抓取目标页面上我们所需要的内容并保存在数据库中.这里的测试案例选用了一个我常用的电影下载网站(http://www.80s.la/).本来是想抓取网站上的所有电影的下载链接,后来感觉需要的时间太长,因此改成了抓取2015年电影的下载链接. 一 原理简介 其实原理都跟第一篇文章差不多,不同的是鉴于这个网站的分类列表实在太多,如果不对这些标签加以取舍的话,需要花费的时间难以想象. 分类链接和标签链接都不要,不通过这些链接去爬取其他页面,只通过页底的

  • 一个简易的Java多页面队列爬虫程序

    之前写过很多单页面python爬虫,感觉python还是很好用的,这里用java总结一个多页面的爬虫,迭代爬取种子页面的所有链接的页面,全部保存在tmp路径下. 一. 序言 实现这个爬虫需要两个数据结构支持,unvisited队列(priorityqueue:可以适用pagerank等算法计算出url重要度)和visited表(hashset:可以快速查找url是否存在):队列用于实现宽度优先爬取,visited表用于记录爬取过的url,不再重复爬取,避免了环.java爬虫需要的工具包有http

  • Java爬虫Jsoup+httpclient获取动态生成的数据

    Java爬虫Jsoup+httpclient获取动态生成的数据 前面我们详细讲了一下Jsoup发现这玩意其实也就那样,只要是可以访问到的静态资源页面都可以直接用他来获取你所需要的数据,详情情跳转-Jsoup爬虫详解,但是很多时候网站为了防止数据被恶意爬取做了很多遮掩,比如说加密啊动态加载啊,这无形中给我们写的爬虫程序造成了很大的困扰,那么我们如何来突破这个梗获取我们急需的数据呢, 下面我们来详细讲解一下如何获取 String startPage="https://item.jd.com/1147

  • Java爬虫实战抓取一个网站上的全部链接

    前言:写这篇文章之前,主要是我看了几篇类似的爬虫写法,有的是用的队列来写,感觉不是很直观,还有的只有一个请求然后进行页面解析,根本就没有自动爬起来这也叫爬虫?因此我结合自己的思路写了一下简单的爬虫. 一 算法简介 程序在思路上采用了广度优先算法,对未遍历过的链接逐次发起GET请求,然后对返回来的页面用正则表达式进行解析,取出其中未被发现的新链接,加入集合中,待下一次循环时遍历. 具体实现上使用了Map<String, Boolean>,键值对分别是链接和是否被遍历标志.程序中使用了两个Map集

  • java 爬虫详解及简单实例

    Java爬虫 一.代码 爬虫的实质就是打开网页源代码进行匹配查找,然后获取查找到的结果. 打开网页: URL url = new URL(http://www.cnblogs.com/Renyi-Fan/p/6896901.html); 读取网页内容: BufferedReader bufr = new BufferedReader(new InputStreamReader(url.openStream())); 正则表达式进行匹配: tring mail_regex = "\\w+@\\w+

  • java实现简单的爬虫之今日头条

    前言 需要提前说下的是,由于今日头条的文章的特殊性,所以无法直接获取文章的地址,需要获取文章的id然后在拼接成url再访问.下面话不多说了,直接上代码. 示例代码如下 public class Demo2 { public static void main(String[] args) { // 需要爬的网页的文章列表 String url = "http://www.toutiao.com/news_finance/"; //文章详情页的前缀(由于今日头条的文章都是在group这个目

  • 分享一个简单的java爬虫框架

    反复给网站编写不同的爬虫逻辑太麻烦了,自己实现了一个小框架 可以自定义的部分有: 请求方式(默认为Getuser-agent为谷歌浏览器的设置),可以通过实现RequestSet接口来自定义请求方式 储存方式(默认储存在f盘的html文件夹下),可以通过SaveUtil接口来自定义保存方式 需要保存的资源(默认为整个html页面) 筛选方式(默认所有url都符合要求),通过实现ResourseChooser接口来自定义需要保存的url和资源页面 实现的部分有: html页面的下载方式,通过Htt

  • java实现一个简单的网络爬虫代码示例

    目前市面上流行的爬虫以python居多,简单了解之后,觉得简单的一些页面的爬虫,主要就是去解析目标页面(html).那么就在想,java有没有用户方便解析html页面呢?找到了一个jsoup包,一个非常方便解析html的工具呢. 使用方式也非常简单,引入jar包: <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.8.

  • Java爬虫框架之WebMagic实战

    一.介绍 WebMagic是一个简单灵活的Java爬虫框架.基于WebMagic,你可以快速开发出一个高效.易维护的爬虫. 二.如何学习 1.查看官网 官网地址为:http://webmagic.io/ 官网详细文档:http://webmagic.io/docs/zh/ 2.跑通hello world示例(具体可以参考官网,也可以参考博客) 我下面写的单元测试案例,可作为Hello World示例. 注意需要导入Maven依赖: <dependency> <groupId>us.

  • 一个简单的python爬虫程序 爬取豆瓣热度Top100以内的电影信息

    概述 这是一个简单的python爬虫程序,仅用作技术学习与交流,主要是通过一个简单的实际案例来对网络爬虫有个基础的认识. 什么是网络爬虫 简单的讲,网络爬虫就是模拟人访问web站点的行为来获取有价值的数据.专业的解释:百度百科 分析爬虫需求 确定目标 爬取豆瓣热度在Top100以内的电影的一些信息,包括电影的名称.豆瓣评分.导演.编剧.主演.类型.制片国家/地区.语言.上映日期.片长.IMDb链接等信息. 分析目标 1.借助工具分析目标网页 首先,我们打开豆瓣电影·热门电影,会发现页面总共20部

  • 简单了解java ORM框架JOOQ

    这篇文章主要介绍了简单了解java ORM框架JOOQ,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 前言 今天给大家介绍一个新的ORM框架->JOOQ,可能很多朋友还没有听说过这个框架,码农哥之前也是一直在使用Mybatis框架作为Java工程中的持久层访问框架,但是最近的一些项目采用JOOQ框架开发后,码农哥表示再也不想用Mybatis了! 为什么这么说呢?因为JOOQ在代码层面要比Mybatis简洁得多,而且性能也非常优异.相信大家都有过

  • 分享一个简单的python读写文件脚本

    先来看一段创建文件并写入文本的代码,然后作介绍. #!/usr/bin/env python 'makeFile.py -- create a file' import os ls = os.linesep # get filename while True: fname = raw_input('Input an unused file name >') if os.path.exists(fname): print "ERROR: '%s' already exists" %

  • 介绍一个简单的JavaScript类框架

    在写work-in-progress JavaScript book一书时,对于javascript继承体系,我花费了相当的时间,并在该过程中研究了各种不同的模拟经典类继承的方案.这些技术方案中,我最为推崇的是base2与Prototype的实现. 从这些方案中,应该能提炼出一个具有其思想内涵的框架,该框架须具有简单.可重用.易于理解并无依赖等特点,其中简单性与可用性是重点.以下是使用示例: var Person = Class. extend ( { init: function (isDan

  • 分享一个简单的sql注入

    所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句.比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到sql注入攻击. 分别输入1,2,3有对应的结果 使用'会报

  • 一个简单的java学生寝室查询系统

    本文实例为大家分享了java学生寝室查询系统的具体代码,供大家参考,具体内容如下 前端部分: index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>AHPU Freshman dormitory inquiry</title> <script src="confirm.js

  • 一个简单的Java音乐播放器

    本文实例为大家分享了Java音乐播放器展示的具体代码,供大家参考,具体内容如下 package KKMusic; import java.applet.Applet; import java.applet.AudioClip; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.borde

随机推荐