spider

  1. import java.io.BufferedReader;
  2. import java.io.InputStreamReader;
  3. import java.net.URL;
  4. import java.net.URLConnection;
  5. import java.util.ArrayList;
  6. import java.util.HashMap;
  7. import java.util.Iterator;
  8. import java.util.List;
  9. import org.htmlparser.RemarkNode;
  10. import org.htmlparser.StringNode;
  11. import org.htmlparser.Node;
  12. import org.htmlparser.tags.*;
  13. import org.htmlparser.Parser;
  14. import org.htmlparser.filters.StringFilter;
  15. import org.htmlparser.util.NodeIterator;
  16. import org.htmlparser.util.NodeList;
  17. import org.htmlparser.util.ParserException;
  18. import java.util.Queue;
  19. import java.util.LinkedList;
  20. public class Spider implements Runnable {
  21. boolean search_key_words = false;
  22. int count = 0;
  23. int limitsite = 10;
  24. int countsite = 1;
  25. String keyword = "中国";//搜索关键字
  26. Parser parser = new Parser();
  27. // List linklist = new ArrayList();
  28. String startsite = "";//搜索的其实站点
  29. SearchResultBean srb;//保存搜索结果
  30. List resultlist = new ArrayList();//搜索到关键字链接列表
  31. List searchedsite = new ArrayList();//已经被搜索站点列表
  32. Queue linklist = new LinkedList();//需解析的链接列表
  33. HashMap<String, ArrayList<String>> disallowListCache = new HashMap<String, ArrayList<String>>();
  34. public Spider(String keyword, String startsite) {
  35.    this.keyword = keyword;
  36.    this.startsite = startsite;
  37.    linklist.add(startsite);
  38.    srb = new SearchResultBean();
  39. }
  40. public void run() {
  41.    // TODO Auto-generated method stub
  42.    search(linklist);
  43. }
  44. public void search(Queue queue) {
  45.    String url = "";
  46.      while(!queue.isEmpty()){
  47.     url = queue.peek().toString();//查找列队
  48.     try {
  49.      if (!isSearched(searchedsite, url)) {
  50.       if (isRobotAllowed(new URL(url)))//检查该链接是否被允许搜索
  51.        processHtml(url);
  52.       else
  53.        System.out.println("this page is disallowed to search");
  54.      }
  55.     } catch (Exception ex) {
  56.     }
  57.     queue.remove();
  58.   
  59.      }
  60.     
  61. }
  62. /**
  63. * 解析HTML
  64. * @param url 
  65. * @throws ParserException
  66. * @throws Exception
  67. */
  68. public void processHtml(String url) throws ParserException, Exception {
  69.    searchedsite.add(url);
  70.    count = 0;
  71.    System.out.println("searching ... :" + url);
  72.    parser.setURL(url);
  73.    parser.setEncoding("GBK");
  74.    URLConnection uc = parser.getConnection();
  75.    uc.connect();
  76.    //uc.getLastModified();
  77.    NodeIterator nit = parser.elements();
  78.   
  79.    while (nit.hasMoreNodes()) {
  80.     Node node = nit.nextNode();
  81.     parserNode(node);
  82.    }
  83.    srb.setKeywords(keyword);
  84.    srb.setUrl(url);
  85.    srb.setCount_key_words(count);
  86.    resultlist.add(srb);
  87.    System.out.println("count keywords is :" + count);
  88.    System.out.println("----------------------------------------------");
  89. }
  90. /**
  91. * 处理HTML标签
  92. * @param tag
  93. * @throws Exception
  94. */
  95. public void dealTag(Tag tag) throws Exception {
  96.    NodeList list = tag.getChildren();
  97.    if (list != null) {
  98.     NodeIterator it = list.elements();
  99.     while (it.hasMoreNodes()) {
  100.      Node node = it.nextNode();
  101.      parserNode(node);
  102.     }
  103.    }
  104. }
  105. /**
  106. * 处理HTML标签结点
  107. * @param node
  108. * @throws Exception
  109. */
  110.     public void parserNode(Node node) throws Exception{
  111.     if (node instanceof StringNode) {//判断是否是文本结点
  112.     StringNode sNode = (StringNode) node;
  113.     StringFilter sf = new StringFilter(keyword,false);
  114.     search_key_words = sf.accept(sNode);
  115.     if (search_key_words) {
  116.      count++;
  117.     }
  118.     // System.out.println("text is :"+sNode.getText().trim());
  119.    } else if (node instanceof Tag) {//判断是否是标签库结点
  120.     Tag atag = (Tag) node;
  121.     if (atag instanceof TitleTag) {//判断是否是标TITLE结点
  122.      srb.setTitle(atag.getText());
  123.     }
  124.     if (atag instanceof LinkTag) {//判断是否是标LINK结点
  125.      LinkTag linkatag = (LinkTag) atag;
  126.      checkLink(linkatag.getLink(), linklist);
  127.      // System.out.println("-----------------this is link --------------");
  128.     }
  129.     dealTag(atag);
  130.    } else if (node instanceof RemarkNode) {//判断是否是注释
  131.     // System.out.println("this is remark");
  132.    }
  133.     }
  134.     /*
  135.      * 检查链接是否需要加入列队
  136.      */
  137. public void checkLink(String link, Queue queue) {
  138.    if (link != null && !link.equals("") && link.indexOf("#") == -1) {
  139.     if (!link.startsWith("http://") && !link.startsWith("ftp://")
  140.       && !link.startsWith("www.")) {
  141.      link = "file:///" + link;
  142.     } else if (link.startsWith("www.")) {
  143.      link = "http://" + link;
  144.     }
  145.     if (queue.isEmpty())
  146.      queue.add(link);
  147.     else {
  148.      String link_end_=link.endsWith("/")?link.substring(0,link.lastIndexOf("/")):(link+"/");
  149.      if (!queue.contains(link)&&!queue .contains(link_end_)) {
  150.       queue.add(link);
  151.      }
  152.     }
  153.    }
  154. }
  155. /**
  156. * 检查该链接是否已经被扫描
  157. * @param list
  158. * @param url
  159. * @return
  160. */
  161. public boolean isSearched(List list, String url) {
  162.    String url_end_ = "";
  163.    if (url.endsWith("/")) {
  164.     url_end_ = url.substring(0, url.lastIndexOf("/"));
  165.    } else {
  166.     url_end_ = url + "/";
  167.    }
  168.    if (list.size() > 0) {
  169.     if (list.indexOf(url) != -1 || list.indexOf(url_end_) != -1) {
  170.      return true;
  171.     }
  172.    }
  173.    return false;
  174. }
  175. /**
  176. * 检查URL是否被允许搜索
  177. * @param urlToCheck
  178. * @return
  179. */
  180. private boolean isRobotAllowed(URL urlToCheck) {
  181.    String host = urlToCheck.getHost().toLowerCase();// 获取给出RUL的主机
  182.    // System.out.println("主机="+host);
  183.    // 获取主机不允许搜索的URL缓存
  184.    ArrayList<String> disallowList = disallowListCache.get(host);
  185.    // 如果还没有缓存,下载并缓存。
  186.    if (disallowList == null) {
  187.     disallowList = new ArrayList<String>();
  188.     try {
  189.      URL robotsFileUrl = new URL("http://" + host + "/robots.txt");
  190.      BufferedReader reader = new BufferedReader(
  191.        new InputStreamReader(robotsFileUrl.openStream()));
  192.      // 读robot文件,创建不允许访问的路径列表。
  193.      String line;
  194.      while ((line = reader.readLine()) != null) {
  195.       if (line.indexOf("Disallow:") == 0) {// 是否包含"Disallow:"
  196.        String disallowPath = line.substring("Disallow:"
  197.          .length());// 获取不允许访问路径
  198.        // 检查是否有注释。
  199.        int commentIndex = disallowPath.indexOf("#");
  200.        if (commentIndex != -1) {
  201.         disallowPath = disallowPath.substring(0,
  202.           commentIndex);// 去掉注释
  203.        }
  204.        disallowPath = disallowPath.trim();
  205.        disallowList.add(disallowPath);
  206.       }
  207.      }
  208.      for (Iterator it = disallowList.iterator(); it.hasNext();) {
  209.       System.out.println("Disallow is :" + it.next());
  210.      }
  211.      // 缓存此主机不允许访问的路径。
  212.      disallowListCache.put(host, disallowList);
  213.     } catch (Exception e) {
  214.      return true// web站点根目录下没有robots.txt文件,返回真
  215.     }
  216.    }
  217.    String file = urlToCheck.getFile();
  218.    // System.out.println("文件getFile()="+file);
  219.    for (int i = 0; i < disallowList.size(); i++) {
  220.     String disallow = disallowList.get(i);
  221.     if (file.startsWith(disallow)) {
  222.      return false;
  223.     }
  224.    }
  225.    return true;
  226. }
  227. public static void main(String[] args) {
  228.    Spider ph = new Spider("英超""http://www.microsoft.com");
  229.    try {
  230.     // ph.processHtml();
  231.     Thread search = new Thread(ph);
  232.     search.start();//启动线程
  233.    } catch (Exception ex) {
  234.    }
  235. }
  236. }
  237. --------------------------------------SearchResultBean.java---------------------------------------------------------
  238. public class SearchResultBean {
  239.    String url = "";
  240.    String title = "";
  241.    String keywords = "";
  242.    int count_key_words = 0;
  243. public int getCount_key_words() {
  244. return count_key_words;
  245. }
  246. public void setCount_key_words(int count_key_words) {
  247. this.count_key_words = count_key_words;
  248. }
  249. public String getKeywords() {
  250. return keywords;
  251. }
  252. public void setKeywords(String keywords) {
  253. this.keywords = keywords;
  254. }
  255. public String getTitle() {
  256. return title;
  257. }
  258. public void setTitle(String title) {
  259. this.title = title;
  260. }
  261. public String getUrl() {
  262. return url;
  263. }
  264. public void setUrl(String url) {
  265. this.url = url;
  266. }
  267. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值