(插播)网络爬虫,抓取你想要得东西。

来源:互联网 发布:mt3601 数据手册 编辑:程序博客网 时间:2024/05/18 00:33

工程在下面

最近,有个朋友说,想在一些页面上获取一些关键性得信息。比如,电话,地址等等。一个个页面去找 又很麻烦。这时候,想起了 何不去用“爬虫”去抓取一些想要得东西。省事,省里。好,今天 我们就讲讲,关于爬虫得一些东西。


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


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


说好了这些 我们来说下 爬虫得基本思想。说简单了,就是 宽度优先遍历,大家可能对深度优先遍历比较熟悉。宽度优先遍历那。其实也可以很简单得去理解。把你的电脑理解为一个站点,互联网就是一个网状得散步开来。而我们要做得是从你的站点出发,先访问离你最近,然后绕圈,再然后 访问下一级,这样一圈圈得 访问下去,很像当时在学校学习得图得概念。 那我们就可以把 百度,新浪,。。等这样得网站作为站点,从他本身开始挖掘。


说了 思想我们开始 我们得第一步,首先我们要把,我们得想法来实现他。 第一步,我们要来定义下 我们需要用到得一些类。首先,我们要记住一条那就是访问过得 ,没必要去访问了。那我们就有了 队列得感念,先进先出。我们要有队列得管理类。

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 blocke.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+"\n");System.out.println(filePath);System.out.println(content);} catch (HttpException e) {// TODO Auto-generated catch blockSystem.out.println("Please check your provided http address!");e.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.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() {@Overridepublic boolean accept(org.htmlparser.Node node) {// TODO Auto-generated method stubreturn 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 blocke.printStackTrace();}return links;}}


这里还用到了一个接口

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


搞好了这些 我们来写我们得主类。这里 我就随便定义了一下。

用Test作了主类。

这里设置下 获取得 超时设置 我设置得是 5s,还有 关键字,我设置得是 youku,因为 我抓取得是www.youku.com上面得信息,只要 包含rul中包含youku关键字 。我就全部获取。这里可以根据自己得喜好来抓取。

public static void main(String[] args) {// TODO Auto-generated method stubTest 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() {@Overridepublic boolean accept(String url) {// TODO Auto-generated method stubif(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);}}        }
工程文件
点击打开链接





0 1