zoukankan      html  css  js  c++  java
  • (插播)网络爬虫,抓取你想要得东西。

    project在以下

    近期,有个朋友说。想在一些页面上获取一些关键性得信息。比方,电话。地址等等。一个个页面去找 又非常麻烦。

    这时候,想起了 何不去用“爬虫”去抓取一些想要得东西。省事,省里。好。今天 我们就讲讲,关于爬虫得一些东西。


    这里 自己也是,看了一些关于爬虫得知识,正好,这几日闲来没事。

    做了一个功能小得爬虫。


    这里是使用 java来进行编写得  首先 我们来介绍下。使用得框架,jdk1.6,htmlparser.jar(java 经典訪问html页面得类),httpclient-3.01.jar,logging-1.1.jar,codec-1.4.jar。


    说好了这些 我们来说下 爬虫得基本思想。说简单了,就是 宽度优先遍历,大家可能对深度优先遍历比較熟悉。宽度优先遍历那。事实上也能够非常easy得去理解。把你的电脑理解为一个网站。互联网就是一个网状得散步开来。

    而我们要做得是从你的网站出发,先訪问离你近期,然后绕圈,再然后 訪问下一级,这样一圈圈得 訪问下去。非常像当时在学校学习得图得概念。 那我们就能够把 百度,新浪,。。等这样得网站作为网站,从他本身開始挖掘。


    说了 思想我们開始 我们得第一步。首先我们要把,我们得想法来实现他。 第一步。我们要来定义下 我们须要用到得一些类。首先,我们要记住一条那就是訪问过得 ,不是必需去訪问了。

    那我们就有了 队列得感念,先进先出。我们要有队列得管理类。

    import java.util.LinkedList;
    
    
    public class Queue {
    	private LinkedList queue = new LinkedList();
    	public void enQueue(Object t) {
    		queue.addLast(t);
    	}
    	
    	public Object deQueue() {
    		return queue.removeFirst();
    	}
    	
    	public boolean isQueueEmpty() {
    		return queue.isEmpty();
    	}
    	
    	public boolean contians(Object t) {
    		return queue.contains(t);
    	}
    	
    }
    

    import java.util.HashSet;
    import java.util.Set;
    
    
    public class LinkQueue {
    	private static Set visitedUrl = new HashSet();
    	private static Queue unVisitedUrl = new Queue();
    	
    	public static Queue getUnVisitedUrl(){
    		return unVisitedUrl;
    	}
    	
    	public static void addVisitedUrl(String url) {
    		visitedUrl.add(url);
    	}
    	
    	public static void removeVIsitedUrl(String url){
    		visitedUrl.remove(url);
    	}
    	
    	public static Object unVisitedUrlDeQueue(){
    		return unVisitedUrl.deQueue();
    	}
    	
    	public static void addUnvisitedUrl(String url){
    		if(url != null && !url.trim().equals("") && !visitedUrl.contains(url) && !unVisitedUrl.contians(url)){
    			unVisitedUrl.enQueue(url);
    		}
    	}
    	
    	public static int getVisitedUrlNum(){
    		return visitedUrl.size();
    	}
    	
    	public static boolean unVisitedUrlsEmpty(){
    		
    		return unVisitedUrl.isQueueEmpty();
    	}
    	
    	
    }
    

    写好队列得管理之后 ,我们要写最关键得类那下载页面类和获取页面信息并处理得一个类。

    我这里是 把获取得 title 和 网址 得一些信息写入了 一个文件。大家能够依据 自己得要求,来改动获取得信息得要求和处理得方式。



    import java.io.ByteArrayInputStream;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URLDecoder;
    
    import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.HttpException;
    import org.apache.commons.httpclient.HttpStatus;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.httpclient.params.HttpMethodParams;
    
    
    public class DownLoadFile {
    	public String getFileNameByUrl(String url,String contentType){
    		
    //		url = url.substring(arg0)
    		if(contentType.indexOf("html") != -1){
    			url = url.replaceAll("[\?

    /:*|<>"]http" ,""); return url; }else { return url.replaceAll("[\?

    /:*|<>"]http", "")+"."+contentType.substring(contentType.lastIndexOf("/")+1); } } private void saveToLocal(String data){ // DataOutputStream outputStream; try { // outputStream = new DataOutputStream(new FileOutputStream(new File("/Users/vika/Desktop/url.txt"))); // outputStream.writeUTF(data); // outputStream.flush(); // outputStream.close(); FileWriter fw = new FileWriter("/Users/vika/Desktop/url.txt", true); fw.write(data); fw.close(); // OutputStream output = null; // File file = new File("/Users/vika/Desktop/url.txt"); // output = new FileOutputStream(file); // int tempByte = -1; // while((tempByte=data.read())>0){ // output.write(tempByte); // } // } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public String downloadFile(String url) { String filePath = null; HttpClient httpClient = new HttpClient(); httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000); GetMethod getMethod = new GetMethod(url); getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000); getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler()); try { int code = httpClient.executeMethod(getMethod); if(code != HttpStatus.SC_OK){ System.err.println("Method failed: "+getMethod.getStatusLine()); filePath = null; } InputStream responseBody = getMethod.getResponseBodyAsStream();// 读取为字节数组 // 依据网页 url 生成保存时的文件名称 String content = getMethod.getResponseBodyAsString(); if(content.contains("title")){ content = content.substring(content.indexOf("<title>"), content.indexOf("</title>")); //URLDecoder.decode(content, "UTF-8"); } filePath = getFileNameByUrl(url, getMethod.getResponseHeader( "Content-Type").getValue()); //saveToLocal(new ByteArrayInputStream((filePath+content).getBytes())); saveToLocal(filePath+content+" "); System.out.println(filePath); System.out.println(content); } catch (HttpException e) { // TODO Auto-generated catch block System.out.println("Please check your provided http address!"); e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ getMethod.releaseConnection(); } return filePath; } }




    import java.util.HashSet;
    import java.util.Set;
    
    
    import org.htmlparser.Node;
    import org.htmlparser.NodeFilter;
    import org.htmlparser.Parser;
    import org.htmlparser.filters.NodeClassFilter;
    import org.htmlparser.filters.OrFilter;
    import org.htmlparser.tags.LinkTag;
    import org.htmlparser.util.NodeList;
    import org.htmlparser.util.ParserException;
    
    
    public class HtmlParserTool {
    	public static Set<String> extracLinks(String url,LinkFilter filter){
    		Set<String> links = new HashSet<String>();
    		try {
    			Parser parser = new Parser(url);
    			parser.setEncoding("UTF-8");
    			final NodeFilter frameFilter = new NodeFilter() {
    				
    				@Override
    				public boolean accept(org.htmlparser.Node node) {
    					// TODO Auto-generated method stub
    					return true;
    //					if (node.getText().startsWith("frame src=")) {
    //					    return true;
    //					} else {
    //					    return false;
    //					}
    				}
    			};
    			
    			OrFilter linkFilter = new OrFilter(new NodeClassFilter(LinkTag.class),frameFilter);
    			NodeList list = (NodeList) parser.extractAllNodesThatMatch(linkFilter);
    			
    			for (int i = 0; i < list.size(); i++) {
    				Node tag = (Node) list.elementAt(i);
    				if(tag instanceof LinkTag){
    					LinkTag link = (LinkTag)tag;
    					String linkUrl = link.getLink();
    					if(filter.accept(linkUrl)){
    						links.add(linkUrl);
    					}else {
    						String frame = ((LinkTag) tag).getText();
    //						int start = frame.indexOf("href=");
    //						frame = frame.substring(start);
    //						int end = frame.indexOf(" ");
    //						if(end == -1)
    //							end = frame.indexOf(">");
    //						String frameUrl = frame.substring(5,end - 1);
    						if(filter.accept(frame)){
    							links.add(frame);
    						}
    					}
    				}
    			}
    			
    			
    		} catch (ParserException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return links;
    	}
    }
    


    这里还用到了一个接口

    public interface LinkFilter {
    	 public boolean accept(String url);
    }


    搞好了这些 我们来写我们得主类。

    这里 我就随便定义了一下。

    用Test作了主类。

    这里设置下 获取得 超时设置 我设置得是 5s。还有 keyword,我设置得是 youku。由于 我抓取得是www.youku.com上面得信息,仅仅要 包括rul中包括youkukeyword 。我就所有获取。这里能够依据自己得喜好来抓取。

    public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Test test = new Test();
    		test.crawling(new String[]{"http://www.youku.com/"});
    	}
    	


     private void initCrawlerWithSeeds(String[] seeds)
        {
            for(int i=0;i<seeds.length;i++)
                LinkQueue.addUnvisitedUrl(seeds[i]);
        }
    	
        public void crawling(String[] seeds){
        	LinkFilter filter = new LinkFilter() {
    			
    			@Override
    			public boolean accept(String url) {
    				
    				// TODO Auto-generated method stub
    				if(url.contains("youku"))
    				    return true;
    				else
    				    return false;
    			}
    		};
    		
    		initCrawlerWithSeeds(seeds);
    		
    		while(!LinkQueue.unVisitedUrlsEmpty()
    				&&LinkQueue.getVisitedUrlNum()<=100000){
    			String visitUrl = (String)LinkQueue.unVisitedUrlDeQueue();
    			if(visitUrl == null)
    				continue;
    			DownLoadFile downLoadFile = new DownLoadFile();
    			downLoadFile.downloadFile(visitUrl);
    			LinkQueue.addVisitedUrl(visitUrl);
    			Set<String>links=HtmlParserTool.extracLinks(visitUrl,filter);
    			
    			for(String link:links)
    			{
    			    LinkQueue.addUnvisitedUrl(link);
    			}
    		}
        	
        }
    project文件
    点击打开链接





  • 相关阅读:
    uboot nand erase 的显示错误修复
    Sougo for linux install.
    S3C6410移植uboot2010.3(2)基本的启动信息修改
    S3C6410移植uboot2010.3(4)uboot的dnw功能添加
    S3C6410移植uboot2010.3(3)正常化配置
    ubuntu乱码修复
    应老婆点(20070705 13:11:34)(新浪)
    克己慎独 2008923 13:32:00 (21ic)
    信任(20061229 14:16:32)(新浪)
    不要轻易承诺 2008926 14:42:00 (21ic)
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6697796.html
Copyright © 2011-2022 走看看