编程语言

img caoxu1987728

SpiderWorker类的实现

发表于2008/10/1 22:28:00  352人阅读

 SpiderWorker类的任务:

笼统地说,Spider使用的多线程,把任务分成了很多小任务。Spider类的基本任务是下载一个web站点,并将网页加入到作业中。执行SpiderWorker,获得网页并对其进行处理,即查看是否含有链接,是内部链接、外部链接还是其他链接。然后通过Spider对象返回链接地址,同时加入到作业里面,循环执行。

可能很多人以为Spider类是核心中的核心,其实SpiderWorker类也是重中之重,作用不比Spider类来得差。

具体代码如下:

  1. package com.heaton.bot;
  2. import java.net.MalformedURLException;
  3. import java.net.URL;
  4. /**
  5.  * The SpiderWorker class performs the actual work of
  6.  * spidering pages.  It is implemented as a thread
  7.  * that is created by the spider class.
  8.  */
  9. public class SpiderWorker extends Thread {
  10.   /**
  11.    * The URL that this spider worker
  12.    * should be downloading.
  13.    */
  14.   protected String target;
  15.   /**
  16.    * The owner of this spider worker class,
  17.    * should always be a Spider object.
  18.    * This is the class that this spider
  19.    * worker will send its data to.
  20.    */
  21.   protected Spider owner;
  22.   /**
  23.    * Indicates if the spider is busy or not.
  24.    * true = busy
  25.    * false = idle(空闲)
  26.    */
  27.   protected boolean busy;
  28.   /**
  29.    * A descendant of the HTTP object that
  30.    * this class should be using for HTTP
  31.    * communication. This is usually the
  32.    * HTTPSocket class.
  33.    */
  34.   protected HTTP http;
  35.   /**
  36.    * Constructs a spider worker object.
  37.    *
  38.    * @param owner The owner of this object, usually
  39.    * a Spider object.
  40.    * @param http
  41.    */
  42.   public SpiderWorker(Spider owner,HTTP http)
  43.   {
  44.     this.http = http;
  45.     this.owner = owner;
  46.   }
  47.   /**
  48.    * Returns true of false to indicate if
  49.    * the spider is busy or idle.
  50.    *
  51.    * @return true = busy
  52.    * false = idle
  53.    */
  54.   public boolean isBusy()
  55.   {
  56.     return this.busy;
  57.   }
  58.   /**
  59.    * The run method causes this thread to go idle
  60.    * and wait for a workload. Once a workload is
  61.    * received, the processWorkload method is called
  62.    * to handle the workload.
  63.    */
  64.   public void run()
  65.   {
  66.     for ( ;; ) {
  67.       target = this.owner.getWorkload();
  68.       if ( target==null )
  69.         return;
  70.       owner.getSpiderDone().workerBegin();
  71.       processWorkload();
  72.       owner.getSpiderDone().workerEnd();
  73.     }
  74.   }
  75.   /**
  76.    * The run method actually performs the
  77.    * the workload assigned to this object.
  78.    */
  79.   public void processWorkload()
  80.   {
  81.     try {
  82.       busy = true;
  83.       Log.log(Log.LOG_LEVEL_NORMAL,"Spidering " + target );
  84.       http.send(target,null);
  85.       Attribute typeAttribute = http.getServerHeaders().get("Content-Type");
  86.       // if no content-type at all, its PROBABLY not HTML
  87.       if ( typeAttribute==null )
  88.         return;
  89.       // now check to see if is HTML, ONLY PARSE text type files(namely HTML)
  90.       owner.processPage(http);      
  91.       if ( !typeAttribute.getValue().startsWith("text/") )
  92.         return;
  93.       HTMLParser parse = new HTMLParser();
  94.       parse.source = new StringBuffer(http.getBody());
  95.       //查找 all the links
  96.       while ( !parse.eof() ) 
  97.       {
  98.         char ch = parse.get();
  99.         if ( ch==0 ) {
  100.           HTMLTag tag = parse.getTag();
  101.           Attribute link = tag.get("HREF");
  102.           if ( link==null )
  103.             link = tag.get("SRC");
  104.           if ( link==null )
  105.             continue;
  106.           URL target=null;
  107.           try {
  108.             target = new URL(new URL(this.target),link.getValue());
  109.           } catch ( MalformedURLException e ) {
  110.             Log.log(Log.LOG_LEVEL_TRACE,
  111.                     "Spider found other link: " + link );
  112.             owner.foundOtherLink(link.getValue());
  113.             continue;
  114.           }
  115.           /*
  116.            * 对查询字符串的处理。
  117.            */
  118.           if ( owner.getRemoveQuery() )
  119.             target = URLUtility.stripQuery(target);
  120.           target = URLUtility.stripAnhcor(target);
  121.           if ( target.getHost().equalsIgnoreCase(
  122.                                                 new URL(this.target).getHost()) ) 
  123.           {
  124.             Log.log(Log.LOG_LEVEL_NORMAL,
  125.                     "Spider found internal link: " + target.toString() );
  126.             owner.foundInternalLink(target.toString());
  127.           } else 
  128.           {
  129.             Log.log(Log.LOG_LEVEL_NORMAL,
  130.                     "Spider found external link: " + target.toString() );
  131.             owner.foundExternalLink(target.toString());
  132.           }
  133.         }
  134.       }
  135.       owner.completePage(http,false);
  136.     } catch ( java.io.IOException e ) {
  137.       Log.log(Log.LOG_LEVEL_ERROR,
  138.               "Error loading file("+ target +"): " + e );
  139.       owner.completePage(http,true);
  140.     } catch ( Exception e ) {
  141.       Log.logException(
  142.                       "Exception while processing file("+ target +"): ", e );
  143.       owner.completePage(http,true);
  144.     } finally {
  145.       busy = false;
  146.     }
  147.   }
  148.   /**
  149.    * Returns the HTTP descendant that this
  150.    * object should use for all HTTP communication.
  151.    * 可能暂时没什么用处
  152.    * @return An HTTP descendant object.
  153.    */
  154.   public HTTP getHTTP()
  155.   {
  156.     return http;
  157.   }
  158. }

代码比较冗长,而且有不少其他调用的类,例如,Http、Log、HtmlParser、Parser、Spider、Attribute、HtmlTag、URLUtility等等,涵盖之广,不以言表。革命尚未成功,同志仍需努力啊!

Let‘s Go!

阅读全文
0 0

相关文章推荐

img
取 消
img