Crawler4j的使用

(以下内容全部为转载,供自己查阅用)

下载地址:

http://code.google.com/p/crawler4j/

Crawler4j的使用

网上对于crawler4j这个爬虫的使用的文章很少,Google到的几乎没有,只能自己根据crawler4j的源码进行修改。这个爬虫最大的特点就是简单易用,他连API都不提供。刚开始的时候实在恨不能适应。好在他的源码也提供了几个例子。对于一般的应用大可以直接修改它的例子。

使用方法很简单,直接用Eclipse打开工程。可以看到src下有三个demo例子。说一下最简单的simple例子。

使用crawler4j的关键的继承WebCrawler类实现自己的爬虫类MyCrawler,然后根据需要覆盖WebCrawler的几个函数就可以了。

public boolean shouldVisit(WebURL url) // 根据url进行网页的解析,对返回为TRUE的网页进行抓取。

public void visit(Page page) // 解析网页内容,page类包含了丰富的方法,可以利用这些方法得到网页的内容和属性。

Crawler包
Crawler.CrawController 控制爬虫,先addseed,再开启多个爬虫,并不断监听各个爬虫存活状态。
Crawler.WebCrawler 爬虫
1. Run():不断循环,每次从Frontier拿50条url,对每条url,processPage(curUrl)。
2. processPage(curURL):用PageFetcher.fetch爬取网页,如果curURL有redirect,则将redirect url的url加入Frontier,以后再调度;如果爬取正常,则先进行parse,生成Page,将新urls降入Frontier(新加入url的深度此时确定),调用visit(Page){用户自定义操作}。
Crawler.Configurations 读取crawler4j.properties中的信息
Crawler.PageFetcher 启动IdleConnectionMonitorThread,用fetch(Page, ignoreIfBinary),爬取单个Page页面。是一个static类。
Crawler.Page 一个页面
Crawler.PageFetchStatus 单个页面爬取的配置,如返回爬取状态数字所代表的含义等等。
Crawler.HTMLParser 对HTML源码进行parse,存入Page中。
Crawler.LinkExtractor 抽取出一个HTML页面中包含的所有link。
Crawler.IdleConnectionMonitorThread 用来监听连接器(用来发送get请求,获取页面),其connMgr则负责HTML请求的发送。

url包
url.WebURL 代表一条url,内含docid, depth, url值
url.URLCanonicalizer 将url进行normalize

Frontier包
Frontier.Frontier
Init() 如果resumable,则从env所指home中读取已处理过得urls,scheduleAll加入调度workQueue中。
Frontier.workQueues 要处理的页面集,如果resumable,在构造时会打开对应env中的database(PendingURLsDB),获取上一次遗留的未处理的urls。
Frontier.inprocessPages 当前正在处理的页面集,继承workQueues,存入InProcessPagesDB数据库
Frontier.DocIDServer 对应数据库DocIDs,记录已经见过的页面url。
处理流程:newurl--->workQueues--->inprovessPages--->delete

Robotstxt包,用来判断url是否被允许。

Util包,用来提供一些小工具。

注意点:
1. seed页面深度为0。
2. url去重利用的是DocIDServer.newdocid(url),如果该值大于0,则表示该url以前见过。通过这个机制,所有以前见过的页面都可以被记录识别。
3. 当设定resumable后,程序跑完后就会把PendingURLsDB和DocIDs保存下来。
4. 如果不设定resumable,在运行程序前,会把env对应的home目录清空。

------------------------------------------------------------------------------

由于最近做实验需要使用到大量的新闻语料库,在网上找了一些都不是自己想要的,所以决定自己写个小程序去爬取New York Times(NYT)上的网页新闻。

Java写的爬虫程序有很多,我找了一个叫crawler4j的开源爬虫,这是一个多线程的爬虫,功能比较简单,源代码也比较容易看懂,由于我要对爬虫爬取链接进行一些修改,就直接下了crawler4j的源码加到我自己的工程中。

然后对爬下来的网页进行处理,使用的是htmlparser这个工具,得到了我要的新闻的Title、Publication Time、Discription、正文等信息。为了更好的组织这些信息,我把这些信息存储到XML文档中。

花了两个晚上的时间,爬虫程序可以跑起来了,写程序的时候遇到了几个问题。

1. 在xml中是使用 "\n" 来表示换行的,而在windows中是使用 "\r\n" 来表示换行符的,所以你要是把含有换行符的文本保存到xml文档时他会自动的把 "\r" 转换成转义符 "& #13;" ,要处理掉这个的话,你可以直接把文本里的 "\r" 给删了就行了。

2. 使用Java中的String.replaceAll(regex, replacement)这个函数时又犯了一个很低级的错误,就是如果执行str.replaceAll(regex, replacement) 时并没有改变str本身的值,所以说要替换str自身的某些字符串时需要执行 str=str.replaceAll(regex, replacement) ,没有意识的这个问题的后果就是花了很长时间在纠结我的程序哪儿出问题了,已经是第二次犯这个错误了,以后不能再犯了啊。

3. 爬取国外的网站资源太慢了,程序开了两个小时左右才爬取了3000篇新闻,慢的可怜啊,希望多开几个线程看看能不能提升一点效果,要是是由于网速的原因的话,可能效果不大。

----------------------------------------------------------------------------

Crawler4j的退出问题

这个问题在网上找了好久也没有好的解决方案,网上的说法是这个爬虫只支持手动强制关闭。无奈只能自己看他的源代码,好在他的源代码也不多。目前的解决方案是。。。直接上代码吧

一、edu.uci.ics.crawler4j.crawler.CrawlController类

public CrawlController(String storageFolder) throws Exception {
。。。

// 新建一个监控线程,不知管什么用
// PageFetcher.startConnectionMonitorThread();
}

public <T extends WebCrawler> void start(Class<T> _c, int numberOfCrawlers) {
。。。
// 设置停止标志
sign_stop = false;
while (true) {

。。。
}
// 停止线程
if(sign_stop){
for (int i = 0; i < crawlers.size(); i++) {
crawlers.get(i).setStop(true);
}
return;
}
if (!someoneIsWorking) {

。。。
}

public void stop() {

sign_stop = true;

}

二、edu.uci.ics.crawler4j.crawler.WebCrawler类

// 停止标志
private boolean stop;

public void run() {
onStart();
stop = false;
while (!stop) {
。。。

}
}

爬虫_Crawler4j的使用的更多相关文章

  1. 设计爬虫Hawk背后的故事

    本文写于圣诞节北京下午慵懒的午后.本文偏技术向,不过应该大部分人能看懂. 五年之痒 2016年,能记入个人年终总结的事情没几件,其中一个便是开源了Hawk.我花不少时间优化和推广它,得到的评价还算比较 ...

  2. Scrapy框架爬虫初探——中关村在线手机参数数据爬取

    关于Scrapy如何安装部署的文章已经相当多了,但是网上实战的例子还不是很多,近来正好在学习该爬虫框架,就简单写了个Spider Demo来实践.作为硬件数码控,我选择了经常光顾的中关村在线的手机页面 ...

  3. Python 爬虫模拟登陆知乎

    在之前写过一篇使用python爬虫爬取电影天堂资源的博客,重点是如何解析页面和提高爬虫的效率.由于电影天堂上的资源获取权限是所有人都一样的,所以不需要进行登录验证操作,写完那篇文章后又花了些时间研究了 ...

  4. scrapy爬虫docker部署

    spider_docker 接我上篇博客,为爬虫引用创建container,包括的模块:scrapy, mongo, celery, rabbitmq,连接https://github.com/Liu ...

  5. scrapy 知乎用户信息爬虫

    zhihu_spider 此项目的功能是爬取知乎用户信息以及人际拓扑关系,爬虫框架使用scrapy,数据存储使用mongo,下载这些数据感觉也没什么用,就当为大家学习scrapy提供一个例子吧.代码地 ...

  6. 120项改进:开源超级爬虫Hawk 2.0 重磅发布!

    沙漠君在历时半年,修改无数bug,更新一票新功能后,在今天隆重推出最新改进的超级爬虫Hawk 2.0! 啥?你不知道Hawk干吗用的? 这是采集数据的挖掘机,网络猎杀的重狙!半年多以前,沙漠君写了一篇 ...

  7. Python爬虫小白入门(四)PhatomJS+Selenium第一篇

    一.前言 在上一篇博文中,我们的爬虫面临着一个问题,在爬取Unsplash网站的时候,由于网站是下拉刷新,并没有分页.所以不能够通过页码获取页面的url来分别发送网络请求.我也尝试了其他方式,比如下拉 ...

  8. Python多线程爬虫爬取电影天堂资源

    最近花些时间学习了一下Python,并写了一个多线程的爬虫程序来获取电影天堂上资源的迅雷下载地址,代码已经上传到GitHub上了,需要的同学可以自行下载.刚开始学习python希望可以获得宝贵的意见. ...

  9. QQ空间动态爬虫

    作者:虚静 链接:https://zhuanlan.zhihu.com/p/24656161 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 先说明几件事: 题目的意 ...

随机推荐

  1. ASP.NET 5探险(6):升级ASP.NET 5到beta6

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:微软根据ASP.NET 5的路线图如期发布了beta6,现在我们就来说说beta5升级 ...

  2. memset中的sizeof

    记录memset中的sizeof的用法, unsigned char *buff = (unsigned char*) malloc(128 * sizeof(char)); //错误的:memset ...

  3. JS对Array进行自定制排序

    JS对Array进行自定制排序,简单的做一个记录,代码如下所示: //Test function function myFunction(){ var myArr = new Array(); var ...

  4. Codeforces Round #248 (Div. 2) C. Ryouko's Memory Note

    题目链接:http://codeforces.com/contest/433/problem/C 思路:可以想到,要把某一个数字变成他的相邻中的数字的其中一个,这样总和才会减少,于是我们可以把每个数的 ...

  5. objective-c常用方法列表(总结)

    第1章 Objective-C学习环境准备 1.1 Objective-C基础 1.1.1 Objective-C的发展历程 1.1.2 Objective-C语言的特点 1.1.3 技术架构 1.2 ...

  6. Emacs 之窗口管理

    // */ // ]]> Emacs 之窗口管理 Table of Contents 1. Emacs 窗口相关 1.1. Emacs 里调整 window 大小 1.2. Emacs winn ...

  7. 如何在MFC中添加对话栏

  8. 启动Tomcat服务器报错: Several ports (8005, 8080, 8009) required

    错误记录--更改tomcat端口号方法,Several ports (8005, 8080, 8009) http://blog.csdn.net/xinxin19881112/article/det ...

  9. CDN网络的原理

    来源:http://blog.csdn.net/coolmeme/article/details/9468743 版权声明:本文为博主原创文章,未经博主允许不得转载. 1.用户向浏览器输入www.we ...

  10. 【hibernate 报错】No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer 【get和load的区别】

    报错: HTTP Status 500 - Could not write content: No serializer found for class org.hibernate.proxy.poj ...