crawler4j 爬爬知多少

  1. Crawler是什么?

  crawler4j是一个开源的java爬虫类库,可以用来构建多线程的web爬虫来抓取页面内容。

  2. 如何获取Crawler?

  crawler4j的官方地址在这里,目前版本为4.1。如果你使用Maven,可以通过下面的pom的方式,如直接下载,点击这里

  3. Crawler怎么用?

  crawler4j的使用分为两个步骤:一是实现一个继承自edu.uci.ics.crawler4j.crawler.WebCrawler的爬虫类;另外就是通过CrawController调用实现的爬虫类。

package com.favccxx.favsoft.favcrawler;

import java.util.Set;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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;

public class FavWebCrawler extends WebCrawler {

	private static final Logger logger = LoggerFactory.getLogger(WebCrawler.class);

	private final static Pattern FILTERS = Pattern.compile(".*(\\.(css|js|gif|jpg" + "|png|mp3|mp3|zip|gz))$");

	@Override
	public boolean shouldVisit(Page referringPage, WebURL url) {
		String href = url.getURL().toLowerCase();
		return !FILTERS.matcher(href).matches() && href.startsWith("http://www.oschina.net/");
	}

	/**
	 * 处理抓取到的页面时,调用该方法	 
	 */
	@Override
	public void visit(Page page) {
		int docid = page.getWebURL().getDocid();
		String url = page.getWebURL().getURL();
		String domain = page.getWebURL().getDomain();
		String path = page.getWebURL().getPath();
		String subDomain = page.getWebURL().getSubDomain();
		String parentUrl = page.getWebURL().getParentUrl();
		String anchor = page.getWebURL().getAnchor();

		logger.debug("Docid: {}", docid);
		logger.info("URL: {}", url);
		logger.debug("Domain: ‘{}‘", domain);
		logger.debug("Sub-domain: ‘{}‘", subDomain);
		logger.debug("Path: ‘{}‘", path);
		logger.debug("Parent page: {}", parentUrl);
		logger.debug("Anchor text: {}", anchor);

		if (page.getParseData() instanceof HtmlParseData) {
			HtmlParseData htmlParseData = (HtmlParseData) page.getParseData();
			String text = htmlParseData.getText();
			String html = htmlParseData.getHtml();
			Set<WebURL> links = htmlParseData.getOutgoingUrls();
			logger.debug("Text length: " + text.length());
			logger.debug("Html length: " + html.length());
			logger.debug("Number of outgoing links: " + links.size());
		}
	}
}
package com.favccxx.favsoft.favcrawler;

import java.util.Set;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.uci.ics.crawler4j.crawler.CrawlConfig;
import edu.uci.ics.crawler4j.crawler.CrawlController;
import edu.uci.ics.crawler4j.crawler.Page;
import edu.uci.ics.crawler4j.crawler.WebCrawler;
import edu.uci.ics.crawler4j.fetcher.PageFetcher;
import edu.uci.ics.crawler4j.parser.HtmlParseData;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer;
import edu.uci.ics.crawler4j.url.WebURL;

public class MyCrawler extends WebCrawler {

	private static final Logger logger = LoggerFactory.getLogger(WebCrawler.class);

	private final static Pattern FILTERS = Pattern.compile(".*(\\.(css|js|gif|jpg"  + "|png|mp3|mp3|zip|gz))$");

	 @Override
     public boolean shouldVisit(Page referringPage, WebURL url) {
         String href = url.getURL().toLowerCase();
         return !FILTERS.matcher(href).matches()
                && href.startsWith("http://www.oschina.net/");
     }

     /**
      * This function is called when a page is fetched and ready
      * to be processed by your program.
      */
     @Override
     public void visit(Page page) {
    	 
    	 int docid = page.getWebURL().getDocid();
 	    String url = page.getWebURL().getURL();
 	    String domain = page.getWebURL().getDomain();
 	    String path = page.getWebURL().getPath();
 	    String subDomain = page.getWebURL().getSubDomain();
 	    String parentUrl = page.getWebURL().getParentUrl();
 	    String anchor = page.getWebURL().getAnchor();
// 	   page.getWebURL().getTag()
 	    
 	    System.out.println("********************************");
// 	    
// 	    System.out.println("Docid: {}" + docid);
// 	    System.out.println("URL: {}"+ url);
// 	    System.out.println("Domain: ‘{}‘"+ domain);
// 	   	System.out.println("Sub-domain: ‘{}‘"+ subDomain);
// 	  	System.out.println("Path: ‘{}‘"+ path);
// 	  	System.out.println("Parent page: {}"+ parentUrl);
// 		System.out.println("Anchor text: {}"+ anchor);

 	    logger.debug("Docid: {}", docid);
 	    logger.info("URL: {}", url);
 	    logger.debug("Domain: ‘{}‘", domain);
 	    logger.debug("Sub-domain: ‘{}‘", subDomain);
 	    logger.debug("Path: ‘{}‘", path);
 	    logger.debug("Parent page: {}", parentUrl);
 	    logger.debug("Anchor text: {}", anchor);
    	 
    	 
//         String url = page.getWebURL().getURL();
         System.out.println("URL: " + url);

         if (page.getParseData() instanceof HtmlParseData) {
             HtmlParseData htmlParseData = (HtmlParseData) page.getParseData();
             String text = htmlParseData.getText();
             String html = htmlParseData.getHtml();
             Set<WebURL> links = htmlParseData.getOutgoingUrls();
             
             System.out.println("--------------------------");
//             System.out.println(text);
             System.out.println("--------------------------");
             System.out.println("Text length: " + text.length());
             System.out.println("Html length: " + html.length());
             System.out.println("Number of outgoing links: " + links.size());
         }
    }
     
    public static void main(String[] args) throws Exception{
    	 String crawlStorageFolder = "/data/crawl/root";
         int numberOfCrawlers = 7;

         CrawlConfig config = new CrawlConfig();
         config.setCrawlStorageFolder(crawlStorageFolder);

         /*
          * Instantiate the controller for this crawl.
          */
         PageFetcher pageFetcher = new PageFetcher(config);
         RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
         RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
         CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);

         /*
          * For each crawl, you need to add some seed urls. These are the first
          * URLs that are fetched and then the crawler starts following links
          * which are found in these pages
          */
         controller.addSeed("http://www.oschina.net/");
//         controller.addSeed("http://www.ics.uci.edu/~welling/");
//         controller.addSeed("http://www.ics.uci.edu/");

         /*
          * Start the crawl. This is a blocking operation, meaning that your code
          * will reach the line after this only when crawling is finished.
          */
         controller.start(MyCrawler.class, numberOfCrawlers);
    }

}

  4. Crawler常用配置

  crawler4j的配置文件都位于edu.uci.ics.crawler4j.crawler.CrawlConfig中,各配置属性的详细说明如下。


crawlStorageFolder:临时存储抓取来的文件的地方,相当于文件中转站。

resumableCrawling:是否重新抓取上一个异常停止/损坏的文件的开关,默认不开启。如果开启该开关,毫无疑问会降低抓取的效率。

maxDepthOfCrawling:抓取的最大深度。默认为-1,即无限深度。

maxPagesToFetch:抓取的最大页面数。默认为-1,即无限抓取。

userAgentString:抓取web服务器的用户代理。默认为“crawler4j (http://code.google.com/p/crawler4j/)”。

politenessDelay:(同一主机的两个请求间的)延迟毫秒数。默认为200。

includeHttpsPages:是否包含Https页面。默认包含。

includeBinaryContentInCrawling:是否包含二进制文件,如image,audio等。默认为不抓取。

maxConnectionsPerHost:每个主机的最大连接数,默认为100。

maxTotalConnections:主机的总共连接数,默认为100。

socketTimeout:socket超时毫秒数,默认为20000。

connectionTimeout:连接超时毫秒数,默认为30000。

maxOutgoingLinksToFollow:每个页面的最大外链数,默认为5000。

maxDownloadSize:每个页面的最大下载容量,默认1048576kb(1024M),超过的部分不会下载。

followRedirects:是否抓取重定向的页面,默认抓取。

proxyHost:代理主机地址,仅在使用代理上网时使用。

proxyPort:代理端口号。

proxyUsername:代理用户名。

proxyPassword:代理密码。

authInfos:授权用户信息。

  

时间: 2025-01-06 07:33:12

crawler4j 爬爬知多少的相关文章

知乎上线“明日头条”,亮剑直指今日头条?

4月1日凌晨,知乎悄然上线了"资讯类内容",并对外宣称发布了"明日头条",意图向移动资讯开始发起进攻.来自知乎内部员工发布的<知乎重磅发布[明日头条],直接促使领结婚证免费>愚人文章中煞有介事地称:"知乎现在正式重磅发布新功能--明日头条,这个划时代新功能将颠覆性地为知乎用户带来全新的内容体验,通过高质量内容的聚合,知乎希望,给世界增加一点颜值." 知乎在这个时候突然推出的"明日头条",着实让人有些惊讶,难道知乎真

腾讯优图及知脸(ZKface)人脸比对接口测试(python)

一.腾讯优图 1.开发者地址:http://open.youtu.qq.com/welcome/developer 2.接入流程:按照开发者页面的接入流程接入之后,创建应用即可获得所需的AppID.SecretID和SecretKey这是进行接口调用必须的凭证 3.测试流程: 3.1.测试可以直接调用网络接口,或者下载相应语言的sdk(http://open.youtu.qq.com/welcome/developer#/tool-sdk),我采用的是下载python版本的sdk(该sdk对应的

肯.威尔伯论觉知

https://tieba.baidu.com/p/4584305679?red_tag=3109625582 1.纯粹的觉知是持续不断的平等的威尔伯重拾消失长达五年之久的写作灵感,他过着离群索居的生活,除了购买日用品之外,几乎完全与世隔绝,三年中只见了四个人,他形容那种情况很像传统的禁语闭关.当时他正埋首于<性.生态学.灵性>这本巨著的撰写工作,他形容其过程就像是一场永无止境的噩梦,为了涵盖四大象限各个领域的知识系统,他需要搜集的资料可想而知有多么博杂了.闭关到第七个月,他患了自称的“渴肤症

仿知乎程序 fragment的切换以及toolbar在不同页面下显示的menu不同

       我们在看知乎的时候,你会发现,首页,发现,关注,收藏,草稿这五项,你在点击之后进入到相应页面之后,侧滑菜单还在,你左侧滑一下,这个侧滑菜单还在,而提问,左滑屏幕,这个页面就没有,有点像返回上一页的感觉. 从操作来看,五页面应该是fragment之间的切换,而提问是单独的activity.     我们先从几个fragment入手,这里我们建立五fragment页,选择继承自android.support.v4.app.Fragment,因为这五个页面基本上都一样,就是简单的一个布局

知问前端——创建header区

创建界面 我们首先要设计一个header,这个区域将要设计成永远置顶.也就是,往下拉出滚动条也永远在页面最上层可视区内.在header区,目前先设计LOGO.搜索框.按钮.注册和登录即可. 项目的大致骨架如下: index.html: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>知问前端</title> <script type=&q

为知发表博客

标题1 标题2 这是在为知笔记中进行的引用 //这是语句块 //hello Word测试程序 void main { printf("hello World"); } 无序列表 列表内容2 添加截图内容名 ? 符号原来是这样插入的啊 来自为知笔记(Wiz)

【美妆讨论】学画日常妆的画法步骤,彩妆入门级别必知

在生活当中,每个女的都必须要知道简单日常妆的画法,这是彩妆中最基本的入门妆容,简单快速的画法,让你给人留下最佳的第一印象,想要知道如何学画日常妆,就看看以下的步骤来学习属于你的日常妆吧! 完成图 步骤一:首先将BB霜点在脸上,用手指指腹将BB霜均匀的推开在脸上.步骤二:用眉笔先勾勒出眉毛的形状,再填补眉毛的空隙处.步骤三:然后就是眼影部分,先用金色的眼影涂抹上眼头部分,再用大地色的眼影涂抹在眼窝处,最后用深咖啡色眼影晕染后半段眼尾,起到加深眼部轮廓的作用. 步骤四:接着用眼线液笔沿着睫毛的根部勾

试读—增长黑客,创业公司必知的“黑科技”

概述 刚一看到书名,最引起注意的是黑客两个字,那个带着神秘色彩,让无数程序员羡慕嫉妒恨的角色.但仔细一看,增长黑客,创业公司必知的"黑科技",是讲公司如何以切实的依据.低廉的成本.可控的风险来达成用户增长.活跃度上升.收入额增加等知识及案例的,这对于初创公司又没有充足的资金去燃烧以改变用户习惯的情况无疑是雪中送炭.指北之针. 什么是增长黑客? 本书适合哪些读者? 增长 靠原始积累实现增长的时代已经过去,也不适合互联网.移动互联网.互联网+的模式.我们经常能看到类似的新闻"某公

Java知多少(42)泛型通配符和类型参数的范围

本节先讲解如何限制类型参数的范围,再讲解通配符(?). 类型参数的范围 在泛型中,如果不对类型参数加以限制,它就可以接受任意的数据类型,只要它是被定义过的.但是,很多时候我们只需要一部分数据类型就够了,用户传递其他数据类型可能会引起错误.例如,编写一个泛型函数用于返回不同类型数组(Integer 数组.Double 数组等)中的最大值: 1 public <T> T getMax(T array[]){ 2 T max = null; 3 for(T element : array){ 4 m