Giter VIP home page Giter VIP logo

jlitespider's Introduction

JLiteSpider

A lite Java spider interface(no a framework).
这是一个轻量级的java爬虫接口(注意:不是一个框架)

###2016.03.20 xylsh更新记录

  1. 按照原版的设计,有2个缺点:
  • 如果要爬取的url很多,加起来的网页总大小很大,会撑爆内存
  • 如果要爬取的url是从分布式队列/数据库/文件等获取的,当前设计不够适应
    所以新版引入了迭代器模式(Iterator),既解决了上面2个问题,而且以"懒加载"的形式,避开巨大数据量时一次性读入内存的负担,Saver在使用爬取结果时才真正发出请求,延迟了爬取动作,带来了性能提升.
  1. Saver.save(K,V)作为存储api,只抽象了存储K/V形式的情况,感觉还是太局限了,改成save(Entry)形式.
  2. 增加异常处理器ErrorProcessor,客户可以控制遇到异常时的处理策略,比如把爬取失败的任务放到队列末尾
  3. 强迫症:
  • 去掉代码中所有TODO Auto-generated catch block
  • 所有tab改成空格

###目的 当前已经有数量庞大的java爬虫框架,他们功能都很强大和完善,用他们来开发一个大型的爬虫任务非常的方便和便捷。但是JLiteSpider和他们并不是同类型的东西,JLiteSpider更像是一个轻量级java爬虫的编写规范。当满足下面几点时,你也许需要JLiteSpider,当然你也可以自己写一个:-(

  • 轻量级的抓取需求
  • 下载,解析和数据持久化都需要深度定制
  • 需要嵌入在其他的系统中

###安装

使用maven:

<dependency>
  <groupId>com.JLiteSpider</groupId>
  <artifactId>JLiteSpider</artifactId>
  <version>1.2</version>
</dependency>

直接下载jar包:

点击下载

###设计

JLiteSpider将整个的爬虫抓取流程抽象成四个部分,由四个接口来定义。在1.2版中,加入了范型的用法,在各个接口中传递的数据类型可以自由定义,从而包含更多的信息,提高灵活度。

1. UrlList:

用来生成想要抓取的url字符串链表。url链表可以由用户进行初始设定,或者由外部传入。

这部分的接口设计如下:

public interface UrlList<T> {
	/**
	 * 返回你想要抓取的url链表
	 * **/
	public List<T> returnUrlList();
}

你所需要做的是,实现这个接口,并将想要抓取的url链表返回。具体的实现细节,可以由你高度定制。

2. Downloader:

这部分实现的是页面下载的任务,将想要抓取的url链表,转化(下载后存储)为相应的页面数据链表。

接口设计如下:

public interface Downloader<D, R> {
	/**
	 * 这个函数将url链表中对应的网页下载,然后将结果保存到链表中,返回
	 * **/
	public List<R> download(List<D> urlList);
}

你同样可以实现这个接口,具体的实现可由你自由定制,只要实现download函数,实现将urlList转化为返回页面的链表的过程。
当然,我在这里提供了一个简单的线程池下载器DefaultDownloader的实现(好让JListSpider看起来不是那么的无用;-))。具体的DefaultDownloader使用方法在后面会讲,不过我还是强烈推荐你能自己实现下载器,这样才能满足更个性化的需求,当然也是JListSpider设计的初衷(只是一个接口)。

3. Saver:

Saver实现的是数据持久化的任务,讲你解析后得到的数据存入数据库,文件等等。

接口的设计:

public interface Saver<T> {
	/**
	 * 将传入此函数的key和value进行持久化操作。
	 * **/
	public void save(String key, T value);
}

通过实现这个接口,可以讲传过来的key和value进行持久化操作。当然,是要持久化到数据库还是文件?是单线程还是线程池操作?这些都需要由你自己来定义。我在extension/中实现了一个打印操作的PrintSaver类,将keyvalue输出到屏幕。

4. Processor:

Processor是解析器的接口,这里会从网页的原始文件中提取出有用的信息,并使用Saver持久化。

接口设计:

public interface Processor<T> {
	/**
	 * pages是传入的要进行解析的文本链表,
	 * 使用saver对象的save(String key, Object value)来完成提取得到的数据的持久化操作
	 * **/
	public void process(List<T> pages, Saver saver);
}

其中process(List<T> pages, Saver saver)中的pages保存的是原始的网页数据链表,saver则是你自定义的数据持久化操作。你所需要做的是,重写这个接口,并定义解析规则,从pages中获取需要的信息,并使用saver进行持久化操作。我在JLiteSpider的包中依赖了JSOUP包,希望对你有用。

###使用方法

JLiteSpider使用:

Spider.create() //创建实例
      .setUrlList(...) //设置实现了UrlList接口的Url生成器
      .setDownloader(...) //设置实现了Downloader接口的下载器
      .setProcessor(...) //设置实现了Processor接口的解析器
      .setSaver(...) //设置实现了Saver接口的数据持久化方法
      .begin(); //开始爬虫

以豆瓣电影的页面为例子:
实现UrlList接口,DoubanUrlList.java

/**
 *  生成,要抓取的url链表
 * 
 * **/
public class DoubanUrlList implements UrlList<String> {

	/**
	 *   notice: 在这个函数中,新建要创建的url链表并返回
	 * **/
	public List<String> returnUrlList() {
		// TODO Auto-generated method stub
		List<String> urlList = new ArrayList<String>();
		urlList.add("http://www.douban.com/tag/**/movie");
		urlList.add("http://www.douban.com/tag/**/movie?start=15");
		urlList.add("http://www.douban.com/tag/**/movie?start=30");
		return urlList;
	}
	
}

实现Processor接口,DoubanProcessor.java:

public class DoubanProcessor implements Processor<String> {

	public void process(List<String> pages, Saver saver) {
		// 将返回的每一个网页中的电影名称和链接,提取出来,使用jsoup
		// 最后使用saver做数据持久化
		for (String each : pages) {
			Document doc = Jsoup.parse(each);
			Element ele = doc.body();
			Elements es = ele.select("div#wrapper").select("div#content")
					.select("div.clearfix").select("div.article")
					.select("div.movie-list").select("dl");
			for (int i = 0; i < es.size(); i++) {
				saver.save("href", es.get(i).select("dt").select("a").attr("href"));
				saver.save("title", es.get(i).select("dd").select("a").text());
			}
		}
	}

}

组装爬虫,DoubanMain.java:

public class DoubanMain {
	private static final String AGENT= "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) "
			+ "AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31";
	public static void main(String[] args) {
		Spider.create().setUrlList(new DoubanUrlList())     //组装UrlList
					   .setDownloader(new DefaultDownloader() //组装下载器
							   .setThreadPoolSize(1)
							   .setUserAgent(AGENT))
					   .setProcessor(new DoubanProcessor())   //组装解析器
					   .setSaver(new PrintSaver())            //组装数据持久化方法
					   .begin();
	}
}

###默认的接口实现

由于JLiteSpider是一个爬虫接口,所以她并没有提供类似其他爬虫框架那样的,很强大的功能实现,而是需要用户的深度定制,实现对应接口的功能。

  • 关于自带的下载器DefaultDownloader的实现,他提供了不少的自定义设置。
setUserAgent(String s) //设置user agent
setCookie(String c) //设置cookie
setTimeout(int t) //设置连接超时时间
setProxy(String p) //设置代理
setThreadPoolSize(int size) //设置线程池的线程数目

看起来好像还可以?最好还是自己实现一个更好的吧!

  • 关于自带的DefaultUrlList实现,可以在构造函数中,将List<String>作为参数传入,实现url链表的初始化操作。
public DefaultUrlList(List<String> u) {
		this.urlList = u;
	}
  • 自带的PrintSaver功能非常简单,只是实现了输出到屏幕的功能。
public class PrintSaver implements Saver<String> {

	public void save(String key, Object value) {
		System.out.println(key+"->"+value);
	}

}

###其他

  • Q: 我需要从网页文件中解析出待抓取的url,然后将其加入下载队列,但是JLiteSpider并没有维护这样一个任务队列。

A: 解决方法是,你可以使用爬虫的嵌套,在获取到url的同时,开启新的爬虫任务,从而完成需求。

  • Q: 我觉得你对于爬虫任务的接口的抽象做得太烂了,有更好的实现。

A: 确实如此,我只是一个新手而已,我渴望能从您那听到更好的解决方案。欢迎提ISSUE。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.