由于最近做实验需要使用到大量的新闻语料库,在网上找了一些都不是自己想要的,所以决定自己写个小程序去爬取New York Times(NYT)上的网页新闻。
用Java写的爬虫程序有很多,我找了一个叫crawler4j的开源爬虫,这是一个多线程的爬虫,功能比较简单,源代码也比较容易看懂,由于我要对爬虫爬取链接进行一些修改,就直接下了crawler4j的源码加到我自己的工程中。
然后对爬下来的网页进行处理,使用的是htmlparser这个工具,得到了我要的新闻的Title、Publication Time、Discription、正文等信息。为了更好的组织这些信息,我把这些信息存储到XML文档中。
花了两个晚上的时间,爬虫程序可以跑起来了,写程序的时候遇到了几个问题。
在xml中是使用 “\n” 来表示换行的,而在windows中是使用 “\r\n” 来表示换行符的,所以你要是把含有换行符的文本保存到xml文档时他会自动的把 “\r” 转换成转义符 “& #13;” ,要处理掉这个的话,你可以直接把文本里的 “\r” 给删了就行了。
使用Java中的String.replaceAll(regex, replacement)这个函数时又犯了一个很低级的错误,就是如果执行str.replaceAll(regex, replacement) 时并没有改变str本身的值,所以说要替换str自身的某些字符串时需要执行 str=str.replaceAll(regex, replacement) ,没有意识的这个问题的后果就是花了很长时间在纠结我的程序哪儿出问题了,已经是第二次犯这个错误了,以后不能再犯了啊。
爬取国外的网站资源太慢了,程序开了两个小时左右才爬取了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) {
。。。
}
}