java开源web爬虫哪个好用

Python018

java开源web爬虫哪个好用,第1张

1.nutch

地址:apache/nutch · GitHub

apache下的开源爬虫程序,功能丰富,文档完整。有数据抓取解析以及存储的模块。

2.Heritrix

地址:internetarchive/heritrix3 · GitHub

很早就有了,经历过很多次更新,使用的人比较多,功能齐全,文档完整,网上的资料也多。有自己的web管理控制台,包含了一个HTTP 服务器。操作者可以通过选择Crawler命令来操作控制台。

3.crawler4j

地址:yasserg/crawler4j · GitHub

因为只拥有爬虫的核心功能,所以上手极为简单,几分钟就可以写一个多线程爬虫程序。

当然,上面说的nutch有的功能比如数据存储不代表Heritrix没有,反之亦然。具体使用哪个合适还需要仔细阅读文档并配合实验才能下结论啊~

还有比如JSpider,WebEater,Java Web Crawler,WebLech,Ex-Crawler,JoBo等等,这些没用过,不知道。。。

网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。

传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。对于垂直搜索来说,聚焦爬虫,即有针对性地爬取特定主题网页的爬虫,更为适合。

以下是一个使用java实现的简单爬虫核心代码:

public void crawl() throws Throwable {

while (continueCrawling()) {

CrawlerUrl url = getNextUrl()//获取待爬取队列中的下一个URL

if (url != null) {

printCrawlInfo()

String content = getContent(url)//获取URL的文本信息

//聚焦爬虫只爬取与主题内容相关的网页,这里采用正则匹配简单处理

if (isContentRelevant(content, this.regexpSearchPattern)) {

saveContent(url, content)//保存网页至本地

//获取网页内容中的链接,并放入待爬取队列中

Collection urlStrings = extractUrls(content, url)

addUrlsToUrlQueue(url, urlStrings)

} else {

System.out.println(url + " is not relevant ignoring ...")

}

//延时防止被对方屏蔽

Thread.sleep(this.delayBetweenUrls)

}

}

closeOutputStream()

}

private CrawlerUrl getNextUrl() throws Throwable {

CrawlerUrl nextUrl = null

while ((nextUrl == null) &&(!urlQueue.isEmpty())) {

CrawlerUrl crawlerUrl = this.urlQueue.remove()

//doWeHavePermissionToVisit:是否有权限访问该URL,友好的爬虫会根据网站提供的"Robot.txt"中配置的规则进行爬取

//isUrlAlreadyVisited:URL是否访问过,大型的搜索引擎往往采用BloomFilter进行排重,这里简单使用HashMap

//isDepthAcceptable:是否达到指定的深度上限。爬虫一般采取广度优先的方式。一些网站会构建爬虫陷阱(自动生成一些无效链接使爬虫陷入死循环),采用深度限制加以避免

if (doWeHavePermissionToVisit(crawlerUrl)

&&(!isUrlAlreadyVisited(crawlerUrl))

&&isDepthAcceptable(crawlerUrl)) {

nextUrl = crawlerUrl

// System.out.println("Next url to be visited is " + nextUrl)

}

}

return nextUrl

}

private String getContent(CrawlerUrl url) throws Throwable {

//HttpClient4.1的调用与之前的方式不同

HttpClient client = new DefaultHttpClient()

HttpGet httpGet = new HttpGet(url.getUrlString())

StringBuffer strBuf = new StringBuffer()

HttpResponse response = client.execute(httpGet)

if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {

HttpEntity entity = response.getEntity()

if (entity != null) {

BufferedReader reader = new BufferedReader(

new InputStreamReader(entity.getContent(), "UTF-8"))

String line = null

if (entity.getContentLength() >0) {

strBuf = new StringBuffer((int) entity.getContentLength())

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

strBuf.append(line)

}

}

}

if (entity != null) {

nsumeContent()

}

}

//将url标记为已访问

markUrlAsVisited(url)

return strBuf.toString()

}

public static boolean isContentRelevant(String content,

Pattern regexpPattern) {

boolean retValue = false

if (content != null) {

//是否符合正则表达式的条件

Matcher m = regexpPattern.matcher(content.toLowerCase())

retValue = m.find()

}

return retValue

}

public List extractUrls(String text, CrawlerUrl crawlerUrl) {

Map urlMap = new HashMap()

extractHttpUrls(urlMap, text)

extractRelativeUrls(urlMap, text, crawlerUrl)

return new ArrayList(urlMap.keySet())

}

private void extractHttpUrls(Map urlMap, String text) {

Matcher m = (text)

while (m.find()) {

String url = m.group()

String[] terms = url.split("a href=\"")

for (String term : terms) {

// System.out.println("Term = " + term)

if (term.startsWith("http")) {

int index = term.indexOf("\"")

if (index >0) {

term = term.substring(0, index)

}

urlMap.put(term, term)

System.out.println("Hyperlink: " + term)

}

}

}

}

private void extractRelativeUrls(Map urlMap, String text,

CrawlerUrl crawlerUrl) {

Matcher m = relativeRegexp.matcher(text)

URL textURL = crawlerUrl.getURL()

String host = textURL.getHost()

while (m.find()) {

String url = m.group()

String[] terms = url.split("a href=\"")

for (String term : terms) {

if (term.startsWith("/")) {

int index = term.indexOf("\"")

if (index >0) {

term = term.substring(0, index)

}

String s = //" + host + term

urlMap.put(s, s)

System.out.println("Relative url: " + s)

}

}

}

}

public static void main(String[] args) {

try {

String url = ""

Queue urlQueue = new LinkedList()

String regexp = "java"

urlQueue.add(new CrawlerUrl(url, 0))

NaiveCrawler crawler = new NaiveCrawler(urlQueue, 100, 5, 1000L,

regexp)

// boolean allowCrawl = crawler.areWeAllowedToVisit(url)

// System.out.println("Allowed to crawl: " + url + " " +

// allowCrawl)

crawler.crawl()

} catch (Throwable t) {

System.out.println(t.toString())

t.printStackTrace()

}

}

有些人问,开发网络爬虫应该选择Nutch、Crawler4j、WebMagic、scrapy、WebCollector还是其他的?这里按照我的经验随便扯淡一下:

上面说的爬虫,基本可以分3类:

1.分布式爬虫:Nutch

2.JAVA单机爬虫:Crawler4j、WebMagic、WebCollector

3. 非JAVA单机爬虫:scrapy

第一类:分布式爬虫

爬虫使用分布式,主要是解决两个问题:

1)海量URL管理

2)网速

现在比较流行的分布式爬虫,是Apache的Nutch。但是对于大多数用户来说,Nutch是这几类爬虫里,最不好的选择,理由如下:

1)Nutch是为搜索引擎设计的爬虫,大多数用户是需要一个做精准数据爬取(精抽取)的爬虫。Nutch运行的一套流程里,有三分之二是为了搜索引擎而设计的。对精抽取没有太大的意义。也就是说,用Nutch做数据抽取,会浪费很多的时间在不必要的计算上。而且如果你试图通过对Nutch进行二次开发,来使得它适用于精抽取的业务,基本上就要破坏Nutch的框架,把Nutch改的面目全非,有修改Nutch的能力,真的不如自己重新写一个分布式爬虫框架了。

2)Nutch依赖hadoop运行,hadoop本身会消耗很多的时间。如果集群机器数量较少,爬取速度反而不如单机爬虫快。

3)Nutch虽然有一套插件机制,而且作为亮点宣传。可以看到一些开源的Nutch插件,提供精抽取的功能。但是开发过Nutch插件的人都知道,Nutch的插件系统有多蹩脚。利用反射的机制来加载和调用插件,使得程序的编写和调试都变得异常困难,更别说在上面开发一套复杂的精抽取系统了。而且Nutch并没有为精抽取提供相应的插件挂载点。Nutch的插件有只有五六个挂载点,而这五六个挂载点都是为了搜索引擎服务的,并没有为精抽取提供挂载点。大多数Nutch的精抽取插件,都是挂载在“页面解析”(parser)这个挂载点的,这个挂载点其实是为了解析链接(为后续爬取提供URL),以及为搜索引擎提供一些易抽取的网页信息(网页的meta信息、text文本)。

4)用Nutch进行爬虫的二次开发,爬虫的编写和调试所需的时间,往往是单机爬虫所需的十倍时间不止。了解Nutch源码的学习成本很高,何况是要让一个团队的人都读懂Nutch源码。调试过程中会出现除程序本身之外的各种问题(hadoop的问题、hbase的问题)。

5)很多人说Nutch2有gora,可以持久化数据到avro文件、hbase、mysql等。很多人其实理解错了,这里说的持久化数据,是指将URL信息(URL管理所需要的数据)存放到avro、hbase、mysql。并不是你要抽取的结构化数据。其实对大多数人来说,URL信息存在哪里无所谓。

6)Nutch2的版本目前并不适合开发。官方现在稳定的Nutch版本是nutch2.2.1,但是这个版本绑定了gora-0.3。如果想用hbase配合nutch(大多数人用nutch2就是为了用hbase),只能使用0.90版本左右的hbase,相应的就要将hadoop版本降到hadoop 0.2左右。而且nutch2的官方教程比较有误导作用,Nutch2的教程有两个,分别是Nutch1.x和Nutch2.x,这个Nutch2.x上写的是可以支持到hbase 0.94。但是实际上,这个Nutch2.x的意思是Nutch2.3之前、Nutch2.2.1之后的一个版本,这个版本在官方的SVN中不断更新。而且非常不稳定(一直在修改)。

所以,如果你不是要做搜索引擎,尽量不要选择Nutch作为爬虫。有些团队就喜欢跟风,非要选择Nutch来开发精抽取的爬虫,其实是冲着Nutch的名气(Nutch作者是Doug Cutting),当然最后的结果往往是项目延期完成。

如果你是要做搜索引擎,Nutch1.x是一个非常好的选择。Nutch1.x和solr或者es配合,就可以构成一套非常强大的搜索引擎了。如果非要用Nutch2的话,建议等到Nutch2.3发布再看。目前的Nutch2是一个非常不稳定的版本。