搜尋引擎背後的秘密 - 網路爬蟲 (Crawler)

程式作品

C 語言

Java

C#

JavaScript

常用函數

文字處理

遊戲程式

衛星定位

系統程式

資料結構

網路程式

自然語言

人工智慧

機率統計

資訊安全

等待完成

訊息

相關網站

參考文獻

最新修改

簡體版

English

程式專案下載:crawler.zip

簡介

搜尋引擎是網際網路興起後最常被使用的工具之一,其主要技術包含前端的全文檢索與後端的網頁蒐集兩類,本文將介紹搜尋引擎後端的網頁蒐集技術 - 并且以 Java 語言實作一個100行左右的網頁蒐集程式 "網路爬蟲 (Crawler)", 然後說明其製作方法與原理。

Google 與 Yahoo 等網站的背後,都有一個強大的網頁蒐集程式,可以將全世界的網頁通通抓回去儲存以便提供搜尋之用,這個程式就稱為 "爬行者 (Crawler)",也有人索性稱為蜘蛛 (Spider),因為這個就好像在網路上爬來爬去的蜘蛛一樣,到處抓網頁回家放。

Crawler 的設計原理,簡要來說是透過程式去追蹤網頁上的超連結,然後不斷往外擴張,以便將全世界中曾經被連結到的網頁全部都抓回到來,這也是 Google, Yahoo 等網站背後最重要的程式之一。

實作

要啟動 Crawler,首先要給一個起始點,以下的範例是利用台灣的 Yahoo 網站作為起始點,並且往下抓兩層,其主程式寫法如下。

  public static void main(String[] args) throws Exception {
    Crawler crawler = new Crawler(2, ""); // 建立一個新的 Crawler, 並設定只抓兩層。
    crawler.addUrl("http://tw.yahoo.com", 1); // 指定從 tw.yahoo.com 開始抓。
    crawler.start();                      // 啟動 Crawler。
  }

以下是 Crawler 的核心程式,其做法是同時執行 10 個 thread 以抓取不同網頁,加快抓取的速度,以下程式在建立 10 個thread 後,會隨時檢查每個 thread 的目前狀況,若有抓到新的網頁,則將其存檔,然後抽取出其中所有的超連結,並將這些超連結放入等待抓取的網址庫中,以便在有 thread 空出來的時候可以繼續抓許下一個網頁。

  public void run() {
    try {
      final int MAX_THREADS = 10;
      HttpThread[] threads = new HttpThread[MAX_THREADS]; // 利用 10 個 thread 同時抓取網頁,以加快抓取速度。
      boolean isAnyOneRunning;
      do {
        isAnyOneRunning = false;
        for (int ti=0; ti<MAX_THREADS; ti++) {
          if (threads[ti] != null && threads[ti].isFinished) { // 若某個 thread 已執行完畢,則將抓回來的網頁放存檔。
            Url url = (Url) urlMap.get(threads[ti].url);
            text2file(threads[ti].text, url.toFileName());
            String[] childUrls = html2urls(threads[ti].text);  // 分解出網頁中的超連結,加入待抓取的網址中。
            for (int ci=0; ci<childUrls.length; ci++) {
            if (childUrls[ci].length() > 256) continue;
            try {
              String fullUrl = fullUrl(url.url, childUrls[ci]);
              addUrl(fullUrl, url.level+1);
            } catch (Exception e) { /*System.out.println("Error : "+childUrls[ci]);*/ }
          }
          threads[ti] = null;
        } // for 
        if (threads[ti] == null && urlIdx < urlList.size()) { 
          // 若某 thread 已執行完畢,則建立一個新的 Thread 以抓取新網頁。
          Url urlNow = (Url) urlList.get(urlIdx++);
          threads[ti] = new HttpThread(urlNow.url);
          threads[ti].start();
        }
        if (threads[ti] != null && !threads[ti].isFinished) // 若有抓到新的網頁,則繼續執行。
          isAnyOneRunning = true;
        }
        sleep(10);
      } while (isAnyOneRunning);
    } catch (Exception e) { e.printStackTrace(); }
  }

結語

Crawler 是搜尋引擎中的關鍵技術,在本文中我們實作了一個簡單的 Crawler ,並以 10 個 thread 平行抓取網頁以加快抓取的速度,這個程式可以用來作為個人抓取網頁個工具程式,作為建立搜尋引擎的基礎。

Facebook

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License