Java 简单的BFS爬虫

来源:互联网 发布:数据库 sql语句 基础 编辑:程序博客网 时间:2024/06/11 02:09

大致意思就是先给定一个URL,然后用HttpParser开源工具提取其网页上的链接,并丢到队列里,然后取队列的首URL重复此操作。

需要用到HttpClient和HttpParser包。

这里先给出所有.Java文件的源码。

其中还有些问题,今天不想看了,所有问题明天再说。

今天做了些修改,还是不能保存到文件,但是应该没有其他的问题了,主要修改了运用Queue来操作,还有修改了提取的Url可能不正确,这里面加了http的判断

-------------------------------------------------------------------------------------MyCrawler.java---------------------------------------------------------------------------------

[java] view plain copy
 print?
  1. package MyCrawler;  
  2.   
  3. import java.util.Set;  
  4.   
  5. /** 
  6.  * 
  7.  * @author xkey 
  8.  */  
  9. public class MyCrawler {  
  10.   
  11.     /** 
  12.      * 使用种子初始化URL队列 
  13.      * @return 
  14.      * @param seeds 种子URL 
  15.      */  
  16.     private static void initCrawlerWithSeeds(String[] seeds)  
  17.     {  
  18.         for(int i = 0 ; i < seeds.length ;  i ++)  
  19.         {  
  20.             LinkQueue.addUnVisitedUrl(seeds[i]);  
  21.         }  
  22.     }  
  23.       
  24.     /** 
  25.      * 抓取过程 
  26.      * @return 
  27.      * @param seeds 
  28.      */  
  29.     public static void crawling (String[] seeds)  
  30.     {  
  31.         initCrawlerWithSeeds(seeds);  
  32.         while(!LinkQueue.unVisitedUrlIsEmpty() && LinkQueue.getVisitedUrlNum() < 1000)  
  33.         {  
  34.             //队头URL  
  35.             String visitUrl = (String)LinkQueue.unVisitedUrlDequeue();  
  36.             System.out.println(visitUrl);  
  37.             if(visitUrl == nullcontinue;  
  38.             DownLoaderFile downLoader = new DownLoaderFile();  
  39.             downLoader.downLoaderFile(visitUrl);  
  40.             LinkQueue.addVisitedUrl(visitUrl);  
  41.             //提取出下载网页中的URL  
  42.             LinkFilter filter = new LinkFilter();  
  43.             Set<String>links = HtmlParserTool.extracLinks(visitUrl);  
  44.             //新的未访问的URL入对  
  45.             for(String link:links)  
  46.             {  
  47.                 System.out.println("xkey: "+link);  
  48.                 LinkQueue.addUnVisitedUrl(link);  
  49.             }  
  50.               
  51.         }  
  52.     }  
  53.     public static  void main(String[] args)  
  54.     {  
  55.         MyCrawler crawler = new MyCrawler();  
  56.         crawler.crawling(new String[]{"http://www.baidu.com"});  
  57.     }  
  58. }  


-------------------------------------------------------------------------------------LinkQueue.java------------------------------------------------------------------------------------

[java] view plain copy
 print?
  1. public class LinkQueue {  
  2.     //已访问的URL集合  
  3.     private static Set visitedUrl = new HashSet();  
  4.     //待访问的URL集合  
  5.     private static Queue <String> unVisitedUrl = new ConcurrentLinkedQueue<String>();  
  6.     //获得URL队列  
  7.      public static Queue getUnVisitedUrl()  
  8.     {  
  9.         return unVisitedUrl;  
  10.     }  
  11.     //添加到访问过的URL队列中  
  12.     public static void addVisitedUrl(String Url)  
  13.     {  
  14.         visitedUrl.add(Url);  
  15.     }  
  16.     //移除访问过的URL  
  17.     public static void removeVisitedUrl(String Url)  
  18.     {  
  19.         visitedUrl.remove(Url);  
  20.     }  
  21.     //未访问过的URL出队列  
  22.     public static Object unVisitedUrlDequeue()  
  23.     {  
  24.         return unVisitedUrl.poll();  
  25.     }  
  26.     //保证每个URL只被访问一次  
  27.     public static void addUnVisitedUrl(String Url)  
  28.     {  
  29.         if(Url != null && !Url.trim().equals("") && !visitedUrl.contains(Url) && !unVisitedUrl.contains(Url))  
  30.             unVisitedUrl.add(Url);  
  31.     }  
  32.     //获得已经访问的URL数目  
  33.     public static int getVisitedUrlNum()  
  34.     {  
  35.         return visitedUrl.size();  
  36.     }  
  37.     //判断未访问的URL队列是否为空  
  38.     public static boolean unVisitedUrlIsEmpty()  
  39.     {  
  40.         return unVisitedUrl.isEmpty();  
  41.     }  
  42. }  




-------------------------------------------------------------------------------------DownLoaderFile.java---------------------------------------------------------------------------------

[java] view plain copy
 print?
  1. public class DownLoaderFile {  
  2.     public String getFileNameByUrl(String url,String contentType)  
  3.     {  
  4.         //移除http  
  5.        url = url.substring(7);  
  6.        //text.html类型  
  7.        if(contentType.indexOf("html") != -1)  
  8.        {  
  9.            url = url.replaceAll("[\\?/:*|<>\"]","_")+".html";  
  10.            return url;  
  11.        }  
  12.        //pdf类型  
  13.        else   
  14.        {  
  15.            return url.replaceAll("[\\?/:*|<>\"]","_")+"."+contentType.substring(contentType.lastIndexOf("/")+1);  
  16.        }  
  17.     }  
  18.     /** 
  19.      * 保存网页字节数组到本地文件,filepath为要保存的文件相对地址 
  20.      */  
  21.     private void saveToLocal(byte[] data,String filePath)  
  22.     {  
  23.         try{  
  24.             DataOutputStream out = new DataOutputStream(new FileOutputStream(new File(filePath)));  
  25.             for(int i = 0 ; i < data.length ; i ++)  
  26.             {  
  27.                 out.write(data[i]);  
  28.             }  
  29.             out.flush();  
  30.             out.close();  
  31.         }catch(IOException e)  
  32.         {  
  33.             e.printStackTrace();  
  34.         }  
  35.     }  
  36.     //下载URL指向的网页  
  37.     public String downLoaderFile(String url)  
  38.     {  
  39.         String filePath = null;  
  40.         //1.生成HttpClient对象并设置参数  
  41.         HttpClient httpClient = new HttpClient();  
  42.         httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);  
  43.         //2.生成GetMethod对象并设置参数  
  44.         GetMethod getMethod = new GetMethod(url);  
  45.         //设置get 请求超时5s  
  46.         getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);  
  47.         getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler());  
  48.         //3.执行http get qi请求  
  49.         try{  
  50.             int statusCode  = httpClient.executeMethod(getMethod);  
  51.             if(statusCode != HttpStatus.SC_OK)  
  52.             {  
  53.                 System.err.println("Method failed: " + getMethod.getStatusLine());  
  54.                 filePath = null;  
  55.             }  
  56.             //4.处理HTTP响应内容  
  57.             byte[] responseBody = getMethod.getResponseBody();  
  58.             //根据网页URL生成保存时的文件名  
  59.            // String ans = new String (responseBody);  
  60.            // System.out.println(ans);  
  61.             //filePath = "D;/xkey";  
  62.           // filePath = "D:\\xkey\\" + getFileNameByUrl(url,getMethod.getResponseHeader("Content-Type").getValue());  
  63.            // saveToLocal(responseBody,filePath);  
  64.         }catch(HttpException e){  
  65.             System.out.println("Please check your provided http address!");  
  66.             e.printStackTrace();  
  67.         }catch (IOException e)  
  68.         {  
  69.             e.printStackTrace();  
  70.         }finally {  
  71.             getMethod.releaseConnection();  
  72.         }  
  73.         return filePath;  
  74.     }  
  75. }  


-------------------------------------------------------------------------------------HttpParserTool.java--------------------------------------------------------------------------------------------------------------

[java] view plain copy
 print?
  1. public class HtmlParserTool {  
  2.     //获取一个网站上的URL,filter用来过滤链接  
  3.     public static Set<String>extracLinks(String url)  
  4.     {  
  5.         Set<String>links = new HashSet<String>();  
  6.         try{  
  7.             Parser parser = new Parser(url);  
  8.             parser.setEncoding("utf-8");  
  9.             NodeFilter frameFilter = new NodeFilter(){  
  10.                 public boolean accept(Node node)  
  11.                 {  
  12.                     if(node.getText().startsWith("frame src=")){  
  13.                         return true;  
  14.                     }  
  15.                     else return false;  
  16.                 }  
  17.             };  
  18.               
  19.             OrFilter linkFilter = new OrFilter(new NodeClassFilter(LinkTag.class),frameFilter);  
  20.             NodeList list = parser.extractAllNodesThatMatch(linkFilter);  
  21.               
  22.             for(int i = 0 ; i < list.size() ; i ++)  
  23.             {  
  24.                 Node tag = list.elementAt(i);  
  25.                 if(tag instanceof LinkTag) //<a>标签  
  26.                 {  
  27.                     LinkTag link = (LinkTag) tag;  
  28.                     String linkUrl = link.getLink();//URL  
  29.                    if(linkUrl.contains("http"))  
  30.                         links.add(linkUrl);  
  31.                 }else {//<frame>标签  
  32.                     //提取frame 里src属性的链接,如<frame src = "test.html">  
  33.                     String frame = tag.getText();  
  34.                     int start = frame.indexOf("src=");  
  35.                     frame = frame.substring(start);  
  36.                     int end = frame.indexOf(" ");  
  37.                     if(end == -1) end = frame.indexOf(">");  
  38.                     String frameUrl = frame.substring(5,end - 1);  
  39.                    if(frameUrl.contains("http"))  
  40.                             links.add(frameUrl);  
  41.                       
  42.                 }  
  43.             }  
  44.         }catch(ParserException e)  
  45.         {  
  46.             e.printStackTrace();  
  47.         }  
  48.         return links;  
  49.     }  
  50. }  
0 0
原创粉丝点击