`
awenhaowenchao
  • 浏览: 72139 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用Heritrix爬取国内某最火的电子商城的笔记本信息遇到的问题

阅读更多
    网上的某些资料也说了对Heritrix进行扩展定制即可个性化的从网上爬取自己需要的内容,为建立垂直搜索作做好准备。
    这里主要扩展FrontierScheduler和Extractor两个class,由于是个demo所以比较简单,由于这些代码仅仅是周日下午和今天晚上抽时间些的,故效率上没有可考虑,比如太多的正则,反射方法构造后应该缓存等,仅供参考

    扩展如下:

    class FrontierSchedulerFor360Buy extends FrontierScheduler

    //至于为什么要扩展schedule大家应该都知道,CandidateURI表示代选的链接,那么意思就是对将要进入候选的链接进行业务上的过滤

    注意:这里有个问题,就是如果需要过滤符合某个格式的链接,但是这个格式的链接不是全部过滤,而且也找不到一定的业务规则去过滤,那么就不能在这里过滤了,后面在Extractor中讲解


	protected void schedule(CandidateURI caUri) {
		// TODO Auto-generated method stub
		String url = caUri.toString();
		System.err.println(">>>++++++ " + url);

		if(url.indexOf("dns:www.360buy.com") != -1){
			System.err.println(">>>>>>++++++ " + url);
			this.getController().getFrontier().schedule(caUri);
		}
		if(url.indexOf("http://www.360buy.com/robots.txt") != -1){
			System.err.println(">>>>>>++++++ " + url);
			this.getController().getFrontier().schedule(caUri);
		}

		if(url.indexOf(PATTERN_360_NOTEBOOK)!=-1){
			System.err.println(">>>>>>++++++ " + url);
			this.getController().getFrontier().schedule(caUri);
		}
		
		if(url.matches(this.PATTERN_360_NOTEBOOK_BRAND)){
			if(url.indexOf("670-671-672-0")!=-1){
				return;
			}
			System.err.println(">>>>>>++++++ " + url);
			this.getController().getFrontier().schedule(caUri);
		}
		
	}


     
    class ExtractorFor360Buy extends Extractor
    这里扩展的话基本是对crawlUri的解析,以及对其中的一部分符合业务规则的链接加入到候选的链接(已经加入就需要过滤了,这就遇到了上面红色注意部分说道的问题),这样我们需要直接将链接交由 BdbFrontier 处理,那么根据源码查看,是因为在schedul候选链接CadicateUri的时候,会getPathFromSeed(),所以需要通过反射设置pathFromSeed


以下为具体的异常:

java.lang.NullPointerException
	at org.archive.crawler.datamodel.CandidateURI.getTransHops(CandidateURI.java:382)
	at org.archive.crawler.frontier.AbstractFrontier.applySpecialHandling(AbstractFrontier.java:727)
	at org.archive.crawler.frontier.WorkQueueFrontier.receive(WorkQueueFrontier.java:442)
	at org.archive.crawler.util.SetBasedUriUniqFilter.add(SetBasedUriUniqFilter.java:90)
	at org.archive.crawler.frontier.WorkQueueFrontier.schedule(WorkQueueFrontier.java:427)
	at com.awen.heritrix.ExtractorFor360Buy.extract(ExtractorFor360Buy.java:124)
	at org.archive.crawler.extractor.Extractor.innerProcess(Extractor.java:67)
	at org.archive.crawler.framework.Processor.process(Processor.java:109)
	at org.archive.crawler.framework.ToeThread.processCrawlUri(ToeThread.java:306)
	at org.archive.crawler.framework.ToeThread.run(ToeThread.java:154)


protected void extract(CrawlURI curi) {
		// TODO Auto-generated method stub
		String currentUrl = curi.toString();
		//如果是笔记本品牌的话,直接解析,进行数据的
		if(currentUrl.matches(this.PATTERN_360_NOTEBOOK_BRAND_ABSOLUTE)){
			
			NodeFilter reputation_clild_filter = new AndFilter(new TagNameFilter("span"), 
				      new HasAttributeFilter("class", "reputation"));
			/**
			 * 此filter为笔记本产品的基本信息,标题,价格,评论链接,图片等
			 */
			NodeFilter div_child_filter = new HasChildFilter(reputation_clild_filter);
			NodeFilter product_filter = new HasChildFilter(div_child_filter);
			try {
				parser.setURL(currentUrl);
				//获取品牌的编码http://www.360buy.com/products/670-671-672-[1-9][\\d]*+-0-0-0-0-0-0-1-1-[\\d].html
				String brandNo ="";
				brandNo = currentUrl.substring(currentUrl.indexOf("670-671-672-") + 12, currentUrl.indexOf("-", "http://www.360buy.com/products/670-671-672-".length()));
				NodeList nodeList = parser.parse(product_filter);
				for (int i = 0; i < nodeList.size(); ++i){
					Node node_li = nodeList.elementAt(i);					
					//String node_li_html = node_li.toHtml();使用正则匹配的话效率太低
					
					try {
						
						String content = node_li.toHtml();
						
						String detail="";
						String img="";
						String price="";
						String remark="";
						String review = "";
						
						//产品详情链接
						Pattern pattern = Pattern.compile(this.PATTERN_360_PRODUCT,Pattern.CASE_INSENSITIVE);
						Matcher matcher = pattern.matcher(content);
						if(matcher.find()){
							String temp = matcher.group();
							
							CandidateURI cUri = new CandidateURI(UURIFactory.getInstance(temp));
							//在往BdbFrontier直接加入CandidateURI过程中会调用CandidateURI的getPathFromSeed,由于为保护方法,所以需要反射设置
							Method m = cUri.getClass().getDeclaredMethod("setPathFromSeed", String.class);
							m.setAccessible(true);
							m.invoke(cUri, temp);
							m.setAccessible(false);
							this.getController().getFrontier().schedule(cUri);
							
							detail = temp.substring(temp.lastIndexOf("/")+1, temp.indexOf(".html"));
							System.err.println(detail);
						}
						
						//产品图片链接
						Pattern pattern1 = Pattern.compile(this.PATTERN_360_PRODUCT_IMG,Pattern.CASE_INSENSITIVE);
						Matcher matcher1 = pattern1.matcher(content);
						if(matcher1.find()){
							String temp = matcher1.group();
							this.addLindFromString(curi, temp, "", Link.EMBED_HOP);
							img = temp.substring(temp.lastIndexOf("/")+1, temp.indexOf(".jpg"));
							System.err.println(img);
							this.getController().getFrontier().schedule(new org.archive.crawler.datamodel.CandidateURI(UURIFactory.getInstance(temp)));
						}
						
						//产品评论链接
						Pattern pattern2 = Pattern.compile(this.PATTERN_360_PRODUCT_EVALUATE,Pattern.CASE_INSENSITIVE);
						Matcher matcher2 = pattern2.matcher(content);
						if(matcher2.find()){
							String temp = matcher2.group();
							//this.addLindFromString(curi, temp, "", Link.NAVLINK_HOP);
							review = temp;
						}
						
						
						//价格
						NodeFilter price_filter = new AndFilter(new TagNameFilter("div"), 
							      new HasAttributeFilter("class", "p-price"));
						//名称
						NodeFilter name_filter = new AndFilter(new TagNameFilter("div"), 
							      new HasAttributeFilter("class", "p-name"));			
						
						//获取价格
						Parser parser = new Parser();
						parser.setInputHTML(content);
						NodeList price_list = parser.parse(price_filter);
						TextExtractingVisitor vistior = new TextExtractingVisitor();
						new Parser(price_list.elementAt(0).toHtml()).visitAllNodesWith(vistior);
						price =vistior.getExtractedText();
						
						System.err.println("price = " + price);
						
						//获取名称描述
						Parser parser1 = new Parser();
						parser1.setInputHTML(content);
						NodeList name_list = parser1.parse(name_filter);
						TextExtractingVisitor vistior1 = new TextExtractingVisitor();
						new Parser(name_list.elementAt(0).toHtml()).visitAllNodesWith(vistior1);
						remark = vistior1.getExtractedText();
						
						System.err.println("name = " + remark);
						try {
							File file = new File("/home/awen/360/" + brandNo + "_" + detail + ".txt");
							if(!file.exists()){
								file.createNewFile();
							}
							BufferedWriter bw = new BufferedWriter(new FileWriter(file));
							bw.write(brandNo + ls);//品牌
							bw.write(detail + ls);//详情链接后缀
							bw.write(img + ls);//图片链接后缀
							bw.write(price + ls);//价格
							bw.write(review + ls);//评价链接							
							bw.write(remark + ls);//描述
							bw.flush();
							bw.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					
						
					}  catch (ParserException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (URIException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (SecurityException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (NoSuchMethodException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IllegalArgumentException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
								
					

		        }
			} catch (ParserException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		//如果不是笔记本品牌的话,直接解析
		HttpRecorder recorder = curi.getHttpRecorder();
		ReplayCharSequence rcs = null;
		try {
			rcs = recorder.getReplayCharSequence();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if(rcs==null){
			return;
		}
		
		String content = rcs.toString();
		
		Pattern pattern = Pattern.compile(this.PATTERN_A_HREF, Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(content);
		
		while(matcher.find()){
			String newUrl = matcher.group(2);
			//符合笔记本
			if(newUrl.matches(this.PATTERN_360_NOTEBOOK)){
				System.err.println("————————————————————————————————符合笔记本——————————————————————————");
				//对newUrl进行修改
				newUrl = "http://www.360buy.com/products" + newUrl;
				this.addLindFromString(curi, newUrl, "", Link.NAVLINK_HOP);
			}
			
			//符合笔记本品牌
			if(newUrl.matches(this.PATTERN_360_NOTEBOOK_BRAND)){
				//对newUrl进行修改
				System.err.println("————————————————————————————————符合笔记本品牌——————————————————————————");
				newUrl = "http://www.360buy.com/products/" + newUrl;
				this.addLindFromString(curi, newUrl, "", Link.NAVLINK_HOP);
			}
		}

	}
	
	//将链接加入到候选链接中,如果在Frontier中也对这种格式的链接需要过滤却不能分辨哪些是否需要过滤,而这些链接
	//又必须要抓取,那么可以直接交给BdbFrontier依次上级调用
	private void addLindFromString(CrawlURI curi, String uri, CharSequence context, char hopType){
		try {
			curi.createAndAddLinkRelativeToBase(uri, context, hopType);
		} catch (URIException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}




  • 大小: 19.1 KB
2
0
分享到:
评论
1 楼 David_WeiZheng 2015-05-19  
楼主,你代码里面的常量是什么啊

相关推荐

    扩展Heritrix3指定链接爬取

    在网上找了许多关于Heritrix的资源,但是关于新版本heritrix3的资源很少,最近由于项目需要,认真读了heritrix的源码,扩展了Heritrix3指定链接提取,内容详细,可以在实际中使用。

    网络爬虫Heritrix1.14.4可直接用

    7. **日志和监控**:Heritrix有完善的日志记录系统,可以帮助开发者跟踪爬虫状态,定位问题。同时,它还提供了一些性能指标,如抓取速度、错误率等,方便用户监控爬虫运行情况。 8. **安全性与伦理**:使用Heritrix...

    heritrix爬虫工具的使用

    Heritrix是一款开源的网络...你可以通过阅读源码来深入理解其工作原理,利用配置示例快速开始你的爬虫项目,查阅文档解决遇到的问题。对于初学者,建议先从官方文档和社区论坛开始学习,逐步掌握Heritrix的使用技巧。

    heritrix系统使用.ppt

    为了解决这个问题,可以使用如ELF哈希算法来平均分配URL到不同的队列,从而实现更有效的多线程同步。 在Heritrix系统中,爬取过程可以分为四个关键部分: 1. **Page Fetching**:这是从Frontier获取URI并处理的...

    配置Heritrix及常见问题解决

    Heritrix是一款强大的开源网络爬虫工具,由互联网档案...总的来说,配置Heritrix涉及多个方面,从理解工作流机制到解决实际抓取过程中遇到的问题。通过深入学习和实践,可以有效地利用Heritrix构建自己的网络爬虫系统。

    heritrix 的详细配置 与 使用资料

    在配置过程中可能会遇到的错误是 `java.lang.UnsupportedClassVersionError`,这通常表示你的 Java 运行环境版本与 Heritrix 需要的版本不匹配。解决这个问题的方法是检查你的 JDK 版本,确保它与 Heritrix 的需求...

    Heritrix使用详解与高级开发应用

    Heritrix是一个强大的Java开发的开源网络爬虫,主要用于从互联网上抓取各种资源。它由www.archive.org提供,以其高度的可扩展性而著称,允许开发者自定义抓取逻辑,通过扩展其内置组件来适应不同的抓取需求。本文将...

    Heritrix的使用入门

    Heritrix的启动有多种方式,但最常见的是通过WebUI启动。这需要运行主类`org.archive.crawler.Heritrix`,并且在命令行中指定`lib`目录下的所有jar包。启动命令通常会包含Java内存分配和Heritrix的安装路径。例如,...

    heritrix爬虫安装部署

    ### Heritrix爬虫安装部署知识点详解 #### 一、Heritrix爬虫简介 Heritrix是一款由互联网档案馆(Internet Archive)开发的开源网络爬虫框架,它使用Java语言编写,支持高度定制化的需求。Heritrix的设计初衷是为了...

    Heritrix-1.4.4.src.zip +Heritrix-1.4.4.zip

    "Myeclipse下安装说明及常见问题.txt" 文件提供了在MyEclipse集成开发环境中安装和运行Heritrix的步骤和可能遇到的问题的解决方案。MyEclipse是一种强大的Java EE集成开发环境,对Java项目的支持非常全面,因此它是...

    heritrix-3.4.0-SNAPSHOT-dist.zip

    因此,使用这个版本时,用户可能会遇到一些未解决的问题或者新特性。 Heritrix的特点包括: 1. **模块化设计**:Heritrix的核心组件是高度模块化的,这使得用户可以根据需求自由组合和配置各个组件,如下载器、...

    heritrix1.14.0jar包

    总的来说,Heritrix1.14.0jar包是构建和运行Heritrix爬虫的关键组成部分,它提供了丰富的功能和高度的定制性,使得开发人员能够高效地获取和处理网络上的大量信息。无论是用于学术研究、数据分析还是网站维护,...

    很好的heritrix学习资料

    接下来是"Heritrix使用的初步总结 - 企业应用 - Java - ITeye论坛.mht",这个文件很可能是某个开发者在ITeye论坛上分享的Heritrix使用心得。ITeye论坛是一个中国程序员交流的平台,这类帖子通常包含了实践中的技巧、...

    lucene_heritrix 搜索引擎

    Lucene和Heritrix是两个在信息技术领域中用于搜索引擎构建的重要工具。Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发,它提供了一个简单的API来索引和搜索大量文本数据。Heritrix,另一方面,是一个...

    heritrix 3.1

    在类之间,Heritrix使用依赖注入(Dependency Injection)模式进行通信。例如,`Crawler`实例化时会注入`Seeder`、`Fetcher`和`Parser`等对象,这些对象再根据各自的职责进行协作。这种设计使得系统更灵活,方便扩展...

    Heritrix(windows版)

    Heritrix的配置文件允许你定制爬虫的行为,比如设置爬取深度、定义过滤规则以及指定目标URL。 2. **heritrix-3.1.0-src.zip**:这个文件包含了Heritrix的源代码,适合开发者或者希望对软件进行定制的用户。通过源...

    Heritrix1.14.4(含源码包)

    Heritrix是一款开源的互联网档案爬虫工具,由Internet Archive开发并维护,广泛应用于数据抓取和网络资源保存。Heritrix 1.14.4是该软件的一个较早版本,包含了完整的源码,因此用户可以对其进行深度定制和调试。 ...

Global site tag (gtag.js) - Google Analytics