项目是基于maven 结构的。

首先我们在pom.xml中加入log4j以及log4j驱动类支持;

<!-- 加入log4j支持 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency> <!-- 加入slf4j log4j驱动类 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency> <dependency>
      <groupId>edu.uci.ics</groupId>

      <artifactId>crawler4j</artifactId>

      <version>4.2</version>

 </dependency>
 

log4j.properties配置如下:

log4j.rootLogger = debug,D,E

### debug ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = c://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n ### error ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =c://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ]

然后我们先来定义一个MyCrawler

package com.demo.crawler;

import java.util.Set;
import java.util.regex.Pattern; import edu.uci.ics.crawler4j.crawler.Page;
import edu.uci.ics.crawler4j.crawler.WebCrawler;
import edu.uci.ics.crawler4j.parser.HtmlParseData;
import edu.uci.ics.crawler4j.url.WebURL; /**
* 自定义爬虫类需要继承WebCrawler类,决定哪些url可以被爬以及处理爬取的页面信息
* @author
*
*/
public class MyCrawler extends WebCrawler { /**
* 正则匹配指定的后缀文件
*/
private final static Pattern FILTERS = Pattern.compile(".*(\\.(css|js|gif|jpg"
+ "|png|mp3|mp3|zip|gz))$"); /**
* 这个方法主要是决定哪些url我们需要抓取,返回true表示是我们需要的,返回false表示不是我们需要的Url
* 第一个参数referringPage封装了当前爬取的页面信息
* 第二个参数url封装了当前爬取的页面url信息
*/
@Override
public boolean shouldVisit(Page referringPage, WebURL url) {
String href = url.getURL().toLowerCase(); // 得到小写的url
return !FILTERS.matcher(href).matches() // 正则匹配,过滤掉我们不需要的后缀文件
&& href.startsWith("http://www.baidu.com/"); // url必须是http://wwwbaidu.com/开头,规定站点
} /**
* 当我们爬到我们需要的页面,这个方法会被调用,我们可以尽情的处理这个页面
* page参数封装了所有页面信息
*/
@Override
public void visit(Page page) {
int docid = page.getWebURL().getDocid(); // 获取docid url的唯一识别 类似主键
String url = page.getWebURL().getURL(); // 获取url
String domain = page.getWebURL().getDomain(); // 获取域名
String path = page.getWebURL().getPath(); // 获取路径
String subDomain = page.getWebURL().getSubDomain(); // 获取子域名
String parentUrl = page.getWebURL().getParentUrl(); // 获取上级Url
String anchor = page.getWebURL().getAnchor(); // 获取锚点 System.out.println("docid:"+docid);
System.out.println("url:"+url);
System.out.println("domain:"+domain);
System.out.println("path:"+path);
System.out.println("subDomain:"+subDomain);
System.out.println("parentUrl:"+parentUrl);
System.out.println("anchor:"+anchor);
    
if (page.getParseData() instanceof HtmlParseData) { // 判断是否是html数据
HtmlParseData htmlParseData = (HtmlParseData) page.getParseData(); // 强制类型转换,获取html数据对象
String text = htmlParseData.getText(); // 获取页面纯文本(无html标签)
String html = htmlParseData.getHtml(); // 获取页面Html
Set<WebURL> links = htmlParseData.getOutgoingUrls(); // 获取页面输出链接 System.out.println("纯文本长度: " + text.length());
System.out.println("html长度: " + html.length());
System.out.println("输出链接个数: " + links.size());
} Header[] responseHeaders = page.getFetchResponseHeaders(); // 获取响应头消息
if (responseHeaders != null) {
System.out.println("响应的头消息");
for (Header header : responseHeaders) {
System.out.println(header.getName()+"+"+header.getValue());
}
}
}
}

再写一个控制器Controller:

package com.demo.crawler;

import edu.uci.ics.crawler4j.crawler.CrawlConfig;
import edu.uci.ics.crawler4j.crawler.CrawlController;
import edu.uci.ics.crawler4j.fetcher.PageFetcher;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer; /**
* 爬虫控制器
* @author
*
*/
public class Controller {
public static void main(String[] args) throws Exception {
String crawlStorageFolder = "c:/crawl"; // 定义爬虫数据存储位置
int numberOfCrawlers = 7; // 定义7个爬虫,也就是7个线程 CrawlConfig config = new CrawlConfig(); // 定义爬虫配置
config.setCrawlStorageFolder(crawlStorageFolder); // 设置爬虫文件存储位置

     /*
* 设置请求的频率
* 每1000毫秒,也就是两次请求的间隔至少是1秒
*/
config.setPolitenessDelay(1000); /*
* 设置请求的网页的深度(后面专门会讲) 设置2 为两层
* 默认值-1 无限深度
*/
config.setMaxDepthOfCrawling(2); /*
* 设置爬取的最大网页数 这里设置1000 最多爬取1000次
* 默认值是-1,表示无限制
*/
config.setMaxPagesToFetch(1000); /**
* 是否爬取二进制文件,比如图片,PDF文档,视频之类的东西 这里设置false 不爬取
* 默认值true,爬取
*/
config.setIncludeBinaryContentInCrawling(false); /*
* 这里可以设置代理
* config.setProxyHost("proxyserver.example.com"); // 代理地址
* config.setProxyPort(8080); // 代理端口
*
* 如果使用代理,也可以设置身份认证 用户名和密码
* config.setProxyUsername(username); config.getProxyPassword(password);
*/ /*
* 这个配置假如设置成true,当一个爬虫突然终止或者奔溃,我们可以恢复;
* 默认配置是false;推荐用默认配置,假如设置成true,性能会大打折扣;
*/
config.setResumableCrawling(false);
/*
* 实例化爬虫控制器
*/
PageFetcher pageFetcher = new PageFetcher(config); // 实例化页面获取器
RobotstxtConfig robotstxtConfig = new RobotstxtConfig(); // 实例化爬虫机器人配置 比如可以设置 user-agent // 实例化爬虫机器人对目标服务器的配置,每个网站都有一个robots.txt文件 规定了该网站哪些页面可以爬,哪些页面禁止爬,该类是对robots.txt规范的实现
RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
// 实例化爬虫控制器
CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer); /**
* 配置爬虫种子页面,就是规定的从哪里开始爬,可以配置多个种子页面
*/
controller.addSeed("http://www.baidu.com/");
controller.addSeed("http://www.baidu.com/a/kaiyuan/");
controller.addSeed("http://www.baidu.com/a/bysj/"); /**
* 启动爬虫,爬虫从此刻开始执行爬虫任务,根据以上配置
*/
controller.start(MyCrawler.class, numberOfCrawlers);     

// 休息5秒
Thread.sleep(10 * 1000);

System.out.println("休息10秒");

// 停止爬取
controller.shutdown();
System.out.println("停止爬取");

// 等待结束任务
controller.waitUntilFinish();


  
}
}

运行Controller.

int docid = page.getWebURL().getDocid(); // 获取docid url的唯一识别 类似主键
        String url = page.getWebURL().getURL();  // 获取url
        String domain = page.getWebURL().getDomain(); // 获取域名
        String path = page.getWebURL().getPath();  // 获取路径 
        String subDomain = page.getWebURL().getSubDomain(); // 获取子域名
        String parentUrl = page.getWebURL().getParentUrl(); // 获取上级Url
        String anchor = page.getWebURL().getAnchor(); // 获取锚点
 
        System.out.println("docid:"+docid);
        System.out.println("url:"+url);
        System.out.println("domain:"+domain);
        System.out.println("path:"+path);
        System.out.println("subDomain:"+subDomain);
        System.out.println("parentUrl:"+parentUrl);
        System.out.println("anchor:"+anchor);

Crawler4j快速入门实例的更多相关文章

  1. 实体框架(Entity Framework)快速入门--实例篇

    在上一篇 <实体框架(Entity Framework)快速入门> 中我们简单了解的EF的定义和大体的情况,我们通过一步一步的做一个简单的实际例子来让大家对EF使用有个简单印象,看操作步骤 ...

  2. Rsync快速入门实例(转)

    三种主要数据传输方式 单主机本地目录间数据传输(类似cp) Local: rsync [OPTION...] SRC... [DEST] 借助rcp,ssh等通道来传输数据(类似scp) Access ...

  3. 简单粗暴,详细得不要不要的 JavaWeb快速入门实例(1)

    额,有些标题党的嫌疑,小细节不用在意哈... 前端时间我在写一个系列,是关于JavaWeb的一个入门级项目实战,我的初衷就是打算写给初学者的,希望能对他们有所帮助. 这段时间博主也接触了一些事情,感觉 ...

  4. Hibernate快速入门实例

    Hibernate工程项目创建基本步骤:导包(Hibernate依赖包.SQL驱动包).编写实体类.编写ORM映射配置文件.编写核心配置文件.编写测试驱动. 整个工程项目结构如下图: 一.导包 笔者使 ...

  5. Entity Framework快速入门--ModelFirst

    Entity Framework带给我们的不仅仅是操作上的方便,而且使用上也很是考虑了用户的友好交互,EF4.0与vs2010的完美融合也是我们选择它的一个理由吧.相比Nhibernate微软这方面做 ...

  6. Flask快速入门

    flask快速入门 1.1.三种框架比较 Django: 重武器,内部包含了非常多组件:ORM.Form.ModelForm.缓存.Session.中间件.信号等 Flask:短小精悍,内部没有太多组 ...

  7. Expression Blend实例中文教程(11) - 视觉管理器快速入门Visual State Manager(VSM)

    Visual State Manager,中文又称视觉状态管理器(简称为VSM),是Silverlight 2中引进的一个概念.通过使用VSM,开发人员和设计人员可以轻松的改变项目控件的视觉效果,在项 ...

  8. Expression Blend实例中文教程(9) - 行为快速入门Behaviors

    在Blend强大的设计功能支持下,设计人员和开发人员可以无代码实现Silverlight/WPF动画效果,例如上文介绍的StoryBoard,就是一个典型例子,设计人员和开发人员仅需提供必要元素,即可 ...

  9. Expression Blend实例中文教程(8) - 动画设计快速入门StoryBoard

    上一篇,介绍了Silverlight动画设计基础知识,Silverlight动画是基于时间线的,对于动画的实现,其实也就是对对象属性的修改过程. 而Silverlight动画分类两种类型,From/T ...

随机推荐

  1. 小程序-wx:for

    wx:for (列表渲染) index默认数组下标item默认数组当前项的变量名 数组是对象的形式,单纯写{{item}},结果是[object object]的形式,必须加对象名,并且对象名基本设置 ...

  2. 错误:the apk for your currently selected variant(app-release-unsigned.apk)is not signed.Please specity a signing configuration for this variant(release)

    1:导入android studio project 时总会出现运行处一个红色叉号,这里可以点击选择叉号上面显示的Edit Configurations 查看右下角的错误警告信息.: 2:记录错误: ...

  3. hdu2282 Chocolate 完美匹配 + 拆点

    题意: N个箱子排成一个圈,所有的箱子里的巧克力的数量加起来不大于N,每次可以把箱子里的巧克力向旁边的箱子转移(两个方向),问要让每个箱子里的巧克力不大于1的最小步数. 分析: 把巧克力大于1的箱子拆 ...

  4. 【Oracle】ORA-38171: Insufficient privileges for SQL management object operation

    问题: 使用SQL PLAN MANAGEMENT的时候运行下面的存储过程报错. SYS@GOOD> conn scott/tiger Connected. SCOTT@GOOD> DEC ...

  5. RedHat/CentOS 大文件拆分及合并与md5验证

    [root@tdh55 mnt]# cd /opt/[root@tdh55 opt]# ll -h-rw-r--r--. 1 root root 7.5G May 12 11:19 TDH-Image ...

  6. 【技术累积】【点】【java】【3】编译和反编译

    闲聊 擦,打脸了,但打完了还是得继续写呗,水着水着看呗. 概述 理解的不深入,但是实用. 总而言之:编译,是将书写的代码翻译为机器能够理解的代码:反编译,则是相反的过程. 来源在于语言的等级,一般认为 ...

  7. SpringMVC(一) HelloWorld

    学习新东西的的第一个程序--HelloWorld,以下是SpringMVC的HelloWorld 第一步: 用MAVEN 创建webapp,并添加依赖.(强烈建议使用MAVEN,MAVEN学习书籍和视 ...

  8. IDEA 社区版 点击‘Edit Configurations’打开“Run/Debug Configurations”,里面没有tomcat server选项

    没错 社区版就是没有 “先手动添加Plugins 然后再setting” 方法无效 搜索不到 http://blog.csdn.net/u010666884/article/details/52119 ...

  9. WSDL实例解析

    WSDL的主要文档元素 WSDL文档可以分为两部分.顶部分由抽象定义组成,而底部分则由具体描述组成.抽象部分以独立于平台和语言的方式定义SOAP消息,它们并不包含任何随 机器或语言而变的元素.这就定义 ...

  10. HDU 5307 He is Flying (生成函数+FFT)

    题目传送门 题目大意:给你一个长度为$n$的自然数序列$a$,定义一段区间的权值为这一段区间里所有数的和,分别输出权值为$[0,\sum a_{i}]$的区间的长度之和 想到了生成函数的话,这道题并不 ...