<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    走在架構師的大道上 Jack.Wang's home

    Java, C++, linux c, C#.net 技術,軟件架構,領域建模,IT 項目管理 Dict.CN 在線詞典, 英語學習, 在線翻譯

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      195 Posts :: 3 Stories :: 728 Comments :: 0 Trackbacks
            超簡單的 Web 爬蟲程序,不過可以在他基礎之上改造一下,寫出強大點的爬蟲!
            謝謝提供程序的 blog 友!
           

    /**
     * @author Jack.Wang
     *
     */
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.LinkedHashSet;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    // 搜索Web爬行者
    public class SearchCrawler implements Runnable {

     /*
      * disallowListCache緩存robot不允許搜索的URL。 Robot協議在Web站點的根目錄下設置一個robots.txt文件,
      * 規定站點上的哪些頁面是限制搜索的。
      * 搜索程序應該在搜索過程中跳過這些區域,下面是robots.txt的一個例子:
      * # robots.txt for http://somehost.com/ User-agent:
      * Disallow: /cgi-bin/
      * Disallow: /registration # Disallow robots on registration page
      * Disallow: /login
      */

     private HashMap<String, ArrayList<String>> disallowListCache = new HashMap<String, ArrayList<String>>();
     ArrayList<String> errorList = new ArrayList<String>();// 錯誤信息
     ArrayList<String> result = new ArrayList<String>(); // 搜索到的結果
     String startUrl;// 開始搜索的起點
     int maxUrl;// 最大處理的url數
     String searchString;// 要搜索的字符串(英文)
     boolean caseSensitive = false;// 是否區分大小寫
     boolean limitHost = false;// 是否在限制的主機內搜索

     public SearchCrawler(String startUrl, int maxUrl, String searchString) {
      this.startUrl = startUrl;
      this.maxUrl = maxUrl;
      this.searchString = searchString;
     }

     public ArrayList<String> getResult() {
      return result;
     }

     public void run() {// 啟動搜索線程
      crawl(startUrl, maxUrl, searchString, limitHost, caseSensitive);
     }

     // 檢測URL格式
     private URL verifyUrl(String url) {
      // 只處理HTTP URLs.
      if (!url.toLowerCase().startsWith("http://"))
       return null;
      URL verifiedUrl = null;
      try {
       verifiedUrl = new URL(url);
      } catch (Exception e) {
       return null;
      }
      return verifiedUrl;
     }

     // 檢測robot是否允許訪問給出的URL.
     private boolean isRobotAllowed(URL urlToCheck) {
      String host = urlToCheck.getHost().toLowerCase();// 獲取給出RUL的主機
      // System.out.println("主機="+host);

      // 獲取主機不允許搜索的URL緩存
      ArrayList<String> disallowList = disallowListCache.get(host);

      // 如果還沒有緩存,下載并緩存。
      if (disallowList == null) {
       disallowList = new ArrayList<String>();
       try {
        URL robotsFileUrl = new URL("http://" + host + "/robots.txt");
        BufferedReader reader = new BufferedReader(
          new InputStreamReader(robotsFileUrl.openStream()));

        // 讀robot文件,創建不允許訪問的路徑列表。
        String line;
        while ((line = reader.readLine()) != null) {
         if (line.indexOf("Disallow:") == 0) {// 是否包含"Disallow:"
          String disallowPath = line.substring("Disallow:"
            .length());// 獲取不允許訪問路徑

          // 檢查是否有注釋。
          int commentIndex = disallowPath.indexOf("#");
          if (commentIndex != -1) {
           disallowPath = disallowPath.substring(0,
             commentIndex);// 去掉注釋
          }

          disallowPath = disallowPath.trim();
          disallowList.add(disallowPath);
         }
        }

        // 緩存此主機不允許訪問的路徑。
        disallowListCache.put(host, disallowList);
       } catch (Exception e) {
        return true; // web站點根目錄下沒有robots.txt文件,返回真
       }
      }

      String file = urlToCheck.getFile();
      // System.out.println("文件getFile()="+file);
      for (int i = 0; i < disallowList.size(); i++) {
       String disallow = disallowList.get(i);
       if (file.startsWith(disallow)) {
        return false;
       }
      }

      return true;
     }

     private String downloadPage(URL pageUrl) {
      try {
       // Open connection to URL for reading.
       BufferedReader reader = new BufferedReader(new InputStreamReader(
         pageUrl.openStream()));

       // Read page into buffer.
       String line;
       StringBuffer pageBuffer = new StringBuffer();
       while ((line = reader.readLine()) != null) {
        pageBuffer.append(line);
       }

       return pageBuffer.toString();
      } catch (Exception e) {
      }

      return null;
     }

     // 從URL中去掉"www"
     private String removeWwwFromUrl(String url) {
      int index = url.indexOf("://www.");
      if (index != -1) {
       return url.substring(0, index + 3) + url.substring(index + 7);
      }

      return (url);
     }

     // 解析頁面并找出鏈接
     private ArrayList<String> retrieveLinks(URL pageUrl, String pageContents,
       HashSet crawledList, boolean limitHost) {
      // 用正則表達式編譯鏈接的匹配模式。
      Pattern p = Pattern.compile("<a\\s+href\\s*=\\s*\"?(.*?)[\"|>]",
        Pattern.CASE_INSENSITIVE);
      Matcher m = p.matcher(pageContents);

      ArrayList<String> linkList = new ArrayList<String>();
      while (m.find()) {
       String link = m.group(1).trim();

       if (link.length() < 1) {
        continue;
       }

       // 跳過鏈到本頁面內鏈接。
       if (link.charAt(0) == '#') {
        continue;
       }

       if (link.indexOf("mailto:") != -1) {
        continue;
       }

       if (link.toLowerCase().indexOf("javascript") != -1) {
        continue;
       }

       if (link.indexOf("://") == -1) {
        if (link.charAt(0) == '/') {// 處理絕對地
         link = "http://" + pageUrl.getHost() + ":"
           + pageUrl.getPort() + link;
        } else {
         String file = pageUrl.getFile();
         if (file.indexOf('/') == -1) {// 處理相對地址
          link = "http://" + pageUrl.getHost() + ":"
            + pageUrl.getPort() + "/" + link;
         } else {
          String path = file.substring(0,
            file.lastIndexOf('/') + 1);
          link = "http://" + pageUrl.getHost() + ":"
            + pageUrl.getPort() + path + link;
         }
        }
       }

       int index = link.indexOf('#');
       if (index != -1) {
        link = link.substring(0, index);
       }

       link = removeWwwFromUrl(link);

       URL verifiedLink = verifyUrl(link);
       if (verifiedLink == null) {
        continue;
       }

       /* 如果限定主機,排除那些不合條件的URL */
       if (limitHost
         && !pageUrl.getHost().toLowerCase().equals(
           verifiedLink.getHost().toLowerCase())) {
        continue;
       }

       // 跳過那些已經處理的鏈接.
       if (crawledList.contains(link)) {
        continue;
       }

       linkList.add(link);
      }

      return (linkList);
     }

     // 搜索下載Web頁面的內容,判斷在該頁面內有沒有指定的搜索字符串

     private boolean searchStringMatches(String pageContents,
       String searchString, boolean caseSensitive) {
      String searchContents = pageContents;
      if (!caseSensitive) {// 如果不區分大小寫
       searchContents = pageContents.toLowerCase();
      }

      Pattern p = Pattern.compile("[\\s]+");
      String[] terms = p.split(searchString);
      for (int i = 0; i < terms.length; i++) {
       if (caseSensitive) {
        if (searchContents.indexOf(terms[i]) == -1) {
         return false;
        }
       } else {
        if (searchContents.indexOf(terms[i].toLowerCase()) == -1) {
         return false;
        }
       }
      }

      return true;
     }

     // 執行實際的搜索操作
     public ArrayList<String> crawl(String startUrl, int maxUrls,
       String searchString, boolean limithost, boolean caseSensitive) {

      HashSet<String> crawledList = new HashSet<String>();
      LinkedHashSet<String> toCrawlList = new LinkedHashSet<String>();

      if (maxUrls < 1) {
       errorList.add("Invalid Max URLs value.");
       System.out.println("Invalid Max URLs value.");
      }

      if (searchString.length() < 1) {
       errorList.add("Missing Search String.");
       System.out.println("Missing search String");
      }

      if (errorList.size() > 0) {
       System.out.println("err!!!");
       return errorList;
      }

      // 從開始URL中移出www
      startUrl = removeWwwFromUrl(startUrl);

      toCrawlList.add(startUrl);
      while (toCrawlList.size() > 0) {

       if (maxUrls != -1) {
        if (crawledList.size() == maxUrls) {
         break;
        }
       }

       // Get URL at bottom of the list.
       String url = toCrawlList.iterator().next();

       // Remove URL from the to crawl list.
       toCrawlList.remove(url);

       // Convert string url to URL object.
       URL verifiedUrl = verifyUrl(url);

       // Skip URL if robots are not allowed to access it.
       if (!isRobotAllowed(verifiedUrl)) {
        continue;
       }

       // 增加已處理的URL到crawledList
       crawledList.add(url);
       String pageContents = downloadPage(verifiedUrl);

       if (pageContents != null && pageContents.length() > 0) {
        // 從頁面中獲取有效的鏈接
        ArrayList<String> links = retrieveLinks(verifiedUrl,
          pageContents, crawledList, limitHost);

        toCrawlList.addAll(links);

        if (searchStringMatches(pageContents, searchString,
          caseSensitive)) {
         result.add(url);
         System.out.println(url);
        }
       }

      }
      return result;
     }

     // 主函數
     public static void main(String[] args) {
      SearchCrawler crawler = new SearchCrawler("http://m.tkk7.com/Jack2007/", 20,"jack");
      Thread search = new Thread(crawler);
      System.out.println("Start searching...");
      System.out.println("result:");
      search.start();
      try {
       search.join();
      } catch (InterruptedException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     }
    }





    本博客為學習交流用,凡未注明引用的均為本人作品,轉載請注明出處,如有版權問題請及時通知。由于博客時間倉促,錯誤之處敬請諒解,有任何意見可給我留言,愿共同學習進步。
    posted on 2008-03-24 09:32 Jack.Wang 閱讀(23440) 評論(4)  編輯  收藏 所屬分類: 開發技術

    Feedback

    # re: 超簡單的 Web 爬蟲程序(轉貼) 2008-08-01 15:45 豚豚
    呵呵,正要看這方面的東西呢~
    謝謝啦~  回復  更多評論
      

    # re: 超簡單的 Web 爬蟲程序(轉貼) 2009-11-11 20:30 張牧宇
    有個問題,樓主把爬下來的網頁存到硬盤了嗎,怎么存?  回復  更多評論
      

    # re: 超簡單的 Web 爬蟲程序(轉貼) 2009-11-11 20:31 張牧宇
    有個問題,樓主把爬下來的網頁存到硬盤了嗎,怎么存?

    qq 125474591 加好友聊吧  回復  更多評論
      

    # re: 超簡單的 Web 爬蟲程序(轉貼) 2016-05-26 19:34 abby
    我覺得對于開發者來說,能腳本化編寫爬蟲是一件挺開心的事情( ̄▽ ̄)"。所以我們團隊開發了一個專門讓開發者用簡單的幾行 javascript 就能在云上編寫和運行復雜爬蟲的系統,叫神箭手云爬蟲開發平臺: http://www.shenjianshou.cn 。歡迎同行們來試用拍磚,盡情給俺們提意見。有想法的可以加群討論: 342953471  回復  更多評論
      

    主站蜘蛛池模板: 国产成人无码精品久久久免费| 日本在线观看免费高清| 外国成人网在线观看免费视频| 在线观看亚洲成人| 国产特黄一级一片免费| 亚洲免费观看视频| 免费精品99久久国产综合精品| 亚洲国产精品国自产拍电影| 免费国产黄网站在线观看| 亚洲精品国产专区91在线| 免费看h片的网站| 亚洲日韩国产一区二区三区在线 | 亚洲韩国—中文字幕| 免费国产在线视频| 91在线精品亚洲一区二区| 久久笫一福利免费导航| 亚洲AV无码成人精品区狼人影院| 免费一级毛片正在播放| 爽爽爽爽爽爽爽成人免费观看| 久久精品国产亚洲夜色AV网站| 亚洲黄色免费在线观看| 亚洲精品永久在线观看| 色噜噜AV亚洲色一区二区| 99久久人妻精品免费一区| 四虎亚洲精品高清在线观看| 免费一看一级毛片人| 精品一卡2卡三卡4卡免费视频 | 亚洲日韩看片无码电影| 亚洲精品97久久中文字幕无码| 91免费福利视频| 91嫩草亚洲精品| 免费在线观看理论片| 久久青草免费91观看| 亚洲小说图区综合在线| 亚洲欧洲中文日韩久久AV乱码| 老汉精品免费AV在线播放| 成人精品国产亚洲欧洲| 久久亚洲一区二区| 四虎影视在线永久免费观看| 国产麻豆成人传媒免费观看 | 久久不见久久见免费影院www日本 久久WWW免费人成—看片 |