定向爬虫简单例子

1:url处理和html解析

 


Java代码  收藏代码
  1. package com.xiaoshuo.util;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import org.apache.http.HttpEntity;  
  7. import org.apache.http.HttpResponse;  
  8. import org.apache.http.client.HttpClient;  
  9. import org.apache.http.client.methods.HttpGet;  
  10. import org.apache.http.impl.client.DefaultHttpClient;  
  11. import org.apache.http.util.EntityUtils;  
  12. import org.jsoup.Jsoup;  
  13. import org.jsoup.nodes.Document;  
  14. import org.jsoup.nodes.Element;  
  15. import org.jsoup.select.Elements;  
  16.   
  17. import com.xiaoshuo.to.Chapter;  
  18. import com.xiaoshuo.to.UrlTO;  
  19.   
  20. /** 
  21.  * 解析html的处理类 
  22.  * @author lijunqing 
  23.  * 
  24.  */  
  25. public class PaserUrlUtil {  
  26.       
  27.     private HttpClient httpClient=new DefaultHttpClient();  
  28.       
  29.     /** 
  30.      * 获得html的string字符串 
  31.      * @param url 
  32.      * @return 
  33.      * @throws Exception 
  34.      */  
  35.     public String getHtmlStr(String url) throws Exception {  
  36.         HttpGet httpGet=new HttpGet(url);  
  37.         HttpResponse response;  
  38.         String htmlStr=null;  
  39.         try {  
  40.             response=httpClient.execute(httpGet);  
  41.             HttpEntity entity=response.getEntity();  
  42.             if(entity != null) {  
  43.                 htmlStr=new String(EntityUtils.toString(entity));  
  44.                 htmlStr=new String(htmlStr.getBytes("ISO-8859-1"), "gbk"); // 读取乱码解决  
  45.             }  
  46.         } catch(Exception e) {  
  47.             e.printStackTrace();  
  48.         }  
  49.         return htmlStr;  
  50.     }  
  51.       
  52.     /** 
  53.      * 获得document 
  54.      * @param url 
  55.      * @return 
  56.      * @throws Exception 
  57.      */  
  58.     public Document getDocument(String url) throws Exception{  
  59.         Thread.currentThread().sleep(5000*2);  
  60.         return Jsoup.parse(getHtmlStr(url));  
  61.     }  
  62.       
  63.     /** 
  64.      * 获得种类url连接 
  65.      * @return 
  66.      * @throws Exception  
  67.      */  
  68.     public List getCategoryUrls(String url) throws Exception{  
  69.         Document doc = getDocument(url);  
  70.         List urlList = new ArrayList();  
  71.         Elements elements = doc.select(".navlist").select("li").select("a");  
  72.         String categoryUrl= null;  
  73.         UrlTO urlTO=null;  
  74.         for(Element element:elements){  
  75.             categoryUrl = element.attr("href");  
  76.             urlTO = new UrlTO();  
  77.             urlTO.setDeptValue(1);  
  78.             urlTO.setUrl(categoryUrl);  
  79.             urlList.add(urlTO);  
  80.         }  
  81.         return urlList;  
  82.     }  
  83.       
  84.     /*** 
  85.      * 通过分类url获得所有的该类下书籍url 
  86.      * @param categoryUrl 
  87.      * @return 
  88.      * @throws Exception  
  89.      */  
  90.     public List getBookUrls(String categoryUrl) throws Exception{  
  91.         System.out.println("bookUrls-处理进入 deptvalue-==1-");  
  92.         List urlTOList = new ArrayList();  
  93.         UrlTO urlTO = new UrlTO();  
  94.         urlTO.setDeptValue(2);  
  95.         String nextUrl = getNextBookUrl(categoryUrl);  
  96.         while(nextUrl != null && !nextUrl.trim().equals("")){  
  97.             System.out.println("bookUrls--"+nextUrl);  
  98.             urlTO.setUrl(nextUrl);  
  99.             nextUrl = getNextBookUrl(nextUrl);  
  100.             urlTOList.add(urlTO);  
  101.         }  
  102.         return urlTOList;  
  103.     }  
  104.       
  105.     /** 
  106.      * 获得下一个分页连接 
  107.      * @param categoryUrl 
  108.      * @return 
  109.      * @throws Exception 
  110.      */  
  111.     public String getNextBookUrl(String categoryUrl) throws Exception{  
  112.         Document doc = getDocument(categoryUrl);  
  113.         Elements elements = doc.select("#pagelink").select("strong +a");  
  114.         if(elements == null){  
  115.             return null;  
  116.         }  
  117.         return elements.first().attr("href");  
  118.     }  
  119.       
  120.     /** 
  121.      * 获取每个页面书籍详情url 
  122.      * @param categoryUrl 
  123.      * @return 
  124.      * @throws Exception 
  125.      */  
  126.     public List getDetailUrlList(String categoryUrl) throws Exception{  
  127.         Document doc = getDocument(categoryUrl);  
  128.         Elements elements = doc.select(".grid").select("tr");  
  129.         String detailUrl = null;  
  130.         List urlTOList = new ArrayList();  
  131.         UrlTO urlTO = new UrlTO();  
  132.         for(Element element:elements){  
  133.           detailUrl =  element.select("td").first().attr("href");  
  134.           urlTO.setDeptValue(3);  
  135.           urlTO.setUrl(detailUrl);  
  136.           urlTOList.add(urlTO);  
  137.         }  
  138.         return urlTOList;  
  139.     }  
  140.       
  141.     public UrlTO getToReadUrl(String detailUrl) throws Exception{  
  142.         Document doc = getDocument(detailUrl);  
  143.         UrlTO urlTO = new UrlTO();  
  144.         String toReadUrl=doc.select("#bt_1").select("a").first().attr("href");  
  145.         urlTO.setDeptValue(4);  
  146.         urlTO.setUrl(toReadUrl);  
  147.         return urlTO;  
  148.     }  
  149.       
  150.     /** 
  151.      * 获得chapter的url 
  152.      * @param url 
  153.      * @return 
  154.      * @throws Exception 
  155.      */  
  156.     public List getChapterList(String detailUrl) throws Exception {  
  157.   
  158.         Document doc= getDocument(detailUrl);  
  159.         Elements elements=doc.select(".list").select("dd").select("a");  
  160.         List urlList=new ArrayList();  
  161.         UrlTO urlTO = new UrlTO();  
  162.         String chapterUrl= null;  
  163.         for(Element element: elements) {  
  164.             chapterUrl = detailUrl + element.attr("href");  
  165.             urlTO.setDeptValue(5);  
  166.             urlTO.setUrl(chapterUrl);  
  167.         }  
  168.         return urlList;  
  169.     }  
  170.       
  171.     /** 
  172.      *  
  173.      * @param chapterUrl 
  174.      * @return 
  175.      * @throws Exception 
  176.      */  
  177.     public Chapter getChapter(String chapterUrl) throws Exception {  
  178.         Document doc=getDocument(chapterUrl);  
  179.         Chapter chapter=new Chapter();  
  180.         String name=doc.select("h1").text();  
  181.         String content=doc.select(".width").text();  
  182.         chapter.setName(name);  
  183.         chapter.setContent(content);  
  184.         return chapter;  
  185.     }  
  186.       
  187. }  

 2:url实体类


Java代码  收藏代码
  1. package com.xiaoshuo.to;  
  2.   
  3. /** 
  4.  * url保存类 
  5.  * @author lijunqing 
  6.  * 
  7.  */  
  8. public class UrlTO {  
  9.   
  10.     private Integer deptValue;  
  11.   
  12.     private String url;  
  13.   
  14.     public Integer getDeptValue() {  
  15.         return deptValue;  
  16.     }  
  17.   
  18.     public void setDeptValue(Integer deptValue) {  
  19.         this.deptValue=deptValue;  
  20.     }  
  21.   
  22.     public String getUrl() {  
  23.         return url;  
  24.     }  
  25.   
  26.     public void setUrl(String url) {  
  27.         this.url=url;  
  28.     }  
  29.       
  30.     public String toString(){  
  31.        return "dept="+deptValue+"--url--"+url;  
  32.     }  
  33.   
  34. }  

 3:队列类


Java代码  收藏代码
  1. package com.xiaoshuo.url;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.LinkedList;  
  5. import java.util.Queue;  
  6. import java.util.Set;  
  7.   
  8. import com.xiaoshuo.to.UrlTO;  
  9.   
  10. /** 
  11.  * 保存访问的url 
  12.  * @author lijunqing 
  13.  */  
  14. public class LinkQueue {  
  15.   
  16.     // 已经访问的url集合  
  17.     private static Set visitedUrl=new HashSet();  
  18.   
  19.     // 未被访问的url集合  
  20.     private static Queue unVisitedUrl=new LinkedList();  
  21.   
  22.     public static Queue getUnVisitedUrl() {  
  23.         return unVisitedUrl;  
  24.     }  
  25.   
  26.     public static void removeVisitedUrl(String url) {  
  27.         visitedUrl.remove(url);  
  28.     }  
  29.   
  30.     public static Object unVisitedPoll() {  
  31.         return unVisitedUrl.poll();  
  32.     }  
  33.       
  34.     public static void addVisitedUrl(String url){  
  35.         System.out.println("已经访问的url--"+url);  
  36.         visitedUrl.add(url);  
  37.     }  
  38.   
  39.     public static void addUnVisitedUrl(UrlTO url) {  
  40.        if(url!= null && !url.getUrl().trim().equals("")&& !visitedUrl.contains(url.getUrl())){  
  41.            System.out.println("想队列中添加新的url"+url.getUrl());  
  42.            unVisitedUrl.offer(url);  
  43.        }  
  44.     }  
  45.   
  46.     public static Integer getVisitedUrlNum() {  
  47.         return visitedUrl.size();  
  48.     }  
  49.   
  50.     public static  boolean unVisitedUrlEmpty() {  
  51.         return unVisitedUrl.isEmpty();  
  52.     }  
  53. }  
  54.  

    4:crawler爬虫类


    Java代码  收藏代码
    1. package com.xiaoshuo.service;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.List;  
    5.   
    6. import org.junit.Test;  
    7.   
    8. import com.xiaoshuo.to.UrlTO;  
    9. import com.xiaoshuo.url.LinkQueue;  
    10. import com.xiaoshuo.util.PaserUrlUtil;  
    11.   
    12. /** 
    13.  * 宽度优先 
    14.  * @author lijunqing 
    15.  * 
    16.  */  
    17. public class Crawler {  
    18.       
    19.     PaserUrlUtil paseUrlUtil = new PaserUrlUtil();  
    20.       
    21.     /** 
    22.      * 初始化种子 
    23.      * @param url 
    24.      */  
    25.     public void initCrawlerBySeed(String url){  
    26.         UrlTO urlTO = new UrlTO();  
    27.         urlTO.setDeptValue(0);  
    28.         urlTO.setUrl(url);  
    29.         LinkQueue.addUnVisitedUrl(urlTO);  
    30.         System.out.println("UrlTO-----"+urlTO);  
    31.     }  
    32.       
    33.     /** 
    34.      * 宽度优先搜索 
    35.      * @throws Exception 
    36.      */  
    37.     public void crawlerByBSF() throws Exception{  
    38.         // 种子url  
    39.         String url = "http://www.shuoshuo520.com/";  
    40.         //种子入队  
    41.         initCrawlerBySeed(url);  
    42.         System.out.println("feeds-----"+url);  
    43.         while(!LinkQueue.unVisitedUrlEmpty()){  
    44.             UrlTO visitUrl = (UrlTO)LinkQueue.unVisitedPoll();  
    45.             if(visitUrl == null)  
    46.                 continue;  
    47.             //放入已经访问的url中  
    48.               
    49.             List unVisitUrlList = null;  
    50.             Integer deptValue = visitUrl.getDeptValue();  
    51.             String nextUrl = visitUrl.getUrl();  
    52.               
    53.             LinkQueue.addVisitedUrl(nextUrl);  
    54.             System.out.println("正在处理的url实体--deptValue--"+deptValue+"--url--"+nextUrl);  
    55.               
    56.             if(deptValue == 0){  
    57.                 unVisitUrlList = paseUrlUtil.getCategoryUrls(nextUrl);  
    58.             }else if(deptValue == 1){  
    59.                 unVisitUrlList = paseUrlUtil.getBookUrls(nextUrl);  
    60.             }else if(deptValue == 2){  
    61.                 unVisitUrlList = paseUrlUtil.getDetailUrlList(nextUrl);  
    62.             }else if(deptValue == 3){  
    63.                 unVisitUrlList = new ArrayList();  
    64.                 unVisitUrlList.add(paseUrlUtil.getToReadUrl(nextUrl));  
    65.             }else if(deptValue == 4){  
    66.                 unVisitUrlList = paseUrlUtil.getChapterList(nextUrl);  
    67.             }else if(deptValue == 5){  
    68.                //最后一层  
    69.             }  
    70.               
    71.             for(UrlTO urlTO: unVisitUrlList){  
    72.                 LinkQueue.addUnVisitedUrl(urlTO);  
    73.                   
    74.             }  
    75.               
    76.               
    77.               
    78.         }  
    79.     }  
    80. }  
     

    5:其实原理差不多,爬虫要定制智能,我的意图是获得该网站数据 到直接插入到数据库中 ,然后建立索引,所以我把每个页面处理封装成对象 插入到数据库中,

    6:爬虫的html解析可以用正则表达式,可以把所有的方法重写一个方法 通过配置文件传递表达式或者参数实现对 其他网站的爬虫数据 

    出处:http://iluoxuan.iteye.com/blog/1718618