用HttpClient和HtmlParser构建的网络爬虫程序

HttpClient是一个很方便进行Http连接操作的工具包,用它可以设置代理和模拟浏览器下载网页。而HtmlParser则是一个开源的,可以对HTML进行处理的工具包,可以很方便的对HTML进行解析。

首先定义一个队列。

import java.util.*; public class Queue { private LinkedList queue; //构造函数 public Queue() { queue=new LinkedList(); } //入队列 public void enQueue(Object elem) { queue.addLast(elem); } //出队列 public Object deQueue() { return queue.removeFirst(); } //判断队列是否为空 public boolean isEmpty() { return queue.isEmpty(); } //判断队列中是否含有某个元素 public boolean contains(Object elem) { return queue.contains(elem); } }

然后定义MyQueue,用于存放已访问的链接和未访问的链接。

import java.util.*; public class MyQueue { //已访问的URL的队列 private Set visitedQueue; //未访问的URL的队列 private Queue unVisitedQueue; //构造函数 public MyQueue() { visitedQueue=new HashSet<String>(); unVisitedQueue=new Queue(); } //加入已访问的队列 public void addURL(String url) { visitedQueue.add(url); } //返回已访问的队列 public Set getVisited() { return this.visitedQueue; } //移除访问过的URL public void removeUrl(String url) { visitedQueue.remove(url); } //未访问过的URL出队列 public String getUnVURL() { return (String)unVisitedQueue.deQueue(); } //加入未访问过的URL public void addUnVURL(String url) { if((url!=null)&&(!url.trim().equals("")&&(!visitedQueue.contains(url))&&(!unVisitedQueue.contains(url)))) { unVisitedQueue.enQueue(url); } } //获得已访问的URL的数目 public int getVisitedNum() { return visitedQueue.size(); } //判断未访问的队列是否为空 public boolean isEmpty() { return unVisitedQueue.isEmpty(); } }

接下来就是用HttpClient下载网页的类。

import java.io.*; import org.apache.commons.httpclient.Header; 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; public class DownLoad { private HttpClient httpClient; public DownLoad() { httpClient=new HttpClient(); } //根据路径下载页面 public String downLoadPage(String path) throws HttpException, IOException { StringBuilder sb=new StringBuilder(); GetMethod getMethod=new GetMethod(path); int status=httpClient.executeMethod(getMethod); BufferedReader br=null; if(status==HttpStatus.SC_OK) { br=new BufferedReader(new InputStreamReader(getMethod.getResponseBodyAsStream())); String line=null; while((line=br.readLine())!=null) { sb.append(line); } } else if((status==HttpStatus.SC_MOVED_PERMANENTLY)||(status==HttpStatus.SC_MOVED_TEMPORARILY)||(status==HttpStatus.SC_SEE_OTHER)||(status==HttpStatus.SC_TEMPORARY_REDIRECT)) { Header head=getMethod.getResponseHeader("location"); if(head!=null) { String newURL=head.getValue(); if((newURL==null)||newURL.equals("")) { newURL="/"; GetMethod getMethod1=new GetMethod(newURL); httpClient.equals(getMethod1); br=new BufferedReader(new InputStreamReader(getMethod1.getResponseBodyAsStream())); String line=null; while((line=br.readLine())!=null) { sb.append(line); } } } } return sb.toString(); } //获取网页并且进行保存 public void download(String path) throws IOException { String filename=path.replaceAll("[//?/:*|<>/"]","-")+".html"; BufferedWriter bw=new BufferedWriter(new FileWriter(new File(filename))); bw.write(downLoadPage(path)); bw.flush(); bw.close(); } //用于测试的主函数 /* public static void main(String[] args) { DownLoad downLoad=new DownLoad(); try { System.out.println(downLoad.downLoadPage("http://www.baidu.com")); } catch (HttpException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } */ }

然后是用HtmlParser解析HTML的类:

import java.util.*; import org.htmlparser.Parser; import org.htmlparser.filters.NodeClassFilter; import org.htmlparser.tags.LinkTag; import org.htmlparser.util.NodeList; import org.htmlparser.util.ParserException; public class HTMLParserTool { public static NodeList getHTMLUrls(String url,String pageEncoding) { NodeList nodeList=null; try { Parser parser=new Parser(url); parser.setEncoding(pageEncoding); //设置解析编码格式 nodeList=parser.parse(new NodeClassFilter(LinkTag.class)); } catch(ParserException ex) { System.out.println(ex.getMessage()); } /* if((nodeList!=null)&&(nodeList.size()>0)) { for(int i=0;i<nodeList.size();i++) { System.out.println(((LinkTag)nodeList.elementAt(i)).extractLink()); } } */ return nodeList; } /* //用于进行测试的主函数 public static void main(String[] args) { HTMLParserTool htmlparser=new HTMLParserTool(); htmlparser.getHTMLUrls("http://www.baidu.com","gb2312"); } */ }

最后是一个主函数,就是蜘蛛。

从未访问链接的队列中提取URL,下载其页面,分析其中的链接;并且将本链接放入已访问的链接队列中。

分析出的链接,如果不在已访问链接队列中,那么就放入未访问链接队列中。

反复循环,直至未访问链接队列为空。

import java.io.IOException; import org.htmlparser.util.NodeList; import org.htmlparser.tags.LinkTag; public class Main { MyQueue queue; public Main() { queue=new MyQueue(); } public void initQueue(String[] seeds) { for(int i=0;i<seeds.length;i++) { queue.addUnVURL(seeds[i]); } } public void Crawler(String[] seeds) { initQueue(seeds); while((!queue.isEmpty())&&(queue.getVisitedNum()<=10)) { //获得未访问队列的URL String url=queue.getUnVURL(); if(url==null) { continue; } DownLoad downLoad=new DownLoad(); try { downLoad.download(url); } catch (IOException e) { // TODO Auto-generated catch block System.out.println(e.getMessage()); e.printStackTrace(); } NodeList nodeList=HTMLParserTool.getHTMLUrls(url,"gb2312"); //放入已经访问的队列 queue.addURL(url); System.out.println(queue.getVisitedNum()); System.out.println(url); if((nodeList!=null)&&(nodeList.size()>0)) { for(int i=0;i<nodeList.size();i++) { String url1=((LinkTag)nodeList.elementAt(i)).extractLink(); queue.addUnVURL(url1); } } } } public static void main(String[] args) { Main mainf=new Main(); mainf.Crawler(new String[]{"http://www.baidu.com"}); } }

你可能感兴趣的:(String,null,url,import,download,网络爬虫)