开源JAVA爬虫crawler4j源码分析 - 4 URL管理、URL队列(三)

2014-11-24 07:32:22 · 作者: · 浏览: 2
synchronized (mutex) { try { if (maxPagesToFetch < 0 || scheduledPages < maxPagesToFetch) { workQueues.put(url); scheduledPages++; counters.increment(Counters.ReservedCounterNames.SCHEDULED_PAGES); } } catch (DatabaseException e) { logger.error("Error while puting the url in the work queue."); } } }
单个添加和批量添加,添加到队列的同时设置计数器,多个逻辑有各自的实现类,实现分离,Frontier负责组合这些逻辑,外部只需调用Fontier即可!Frontier还有一方法就是获取队列中的数据,一次可获取多条:

	public void getNextURLs(int max, List
  
    result) {
		while (true) {
			synchronized (mutex) {
				if (isFinished) {
					return;
				}
				try {
					List
   
     curResults = workQueues.get(max); workQueues.delete(curResults.size()); if (inProcessPages != null) { for (WebURL curPage : curResults) { inProcessPages.put(curPage); } } result.addAll(curResults); } catch (DatabaseException e) { logger.error("Error while getting next urls: " + e.getMessage()); e.printStackTrace(); } if (result.size() > 0) { return; } } try { synchronized (waitingList) { waitingList.wait(); } } catch (InterruptedException ignored) { // Do nothing } if (isFinished) { return; } } } 
   
  

爬虫线程每次调用这个方法领取50个URL,领取完就从队列删除,开始解析,解析完后重新调用领取。如果队列是空的,线程将会在这个方法里面等待wait(),其它线程也会在synchronized处排队,直到scheduleAll方法被调用,线程才会重新被激活notifyAll()。


以上就是crawler4j爬虫存储和分配URL的代码分析,涉及的类都被放在了edu.uci.ics.crawler4j.frontier包,该包还有一个类InProcessPagesDB是用来作可恢复爬取的,不做讨论。