疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

java代码抓取网页


 

  从指定的url抓取网页,思路很清晰,使用java.net.URL得到url对应的二进制流,然后就可以像操作普通文件那样操作这个流了。

  下面的例子演示了从百度抓取一个搜索网页,将网页存入到文件当中;同时,还对网页进行了简单的分析,得到了检索结果的数量。

  不过在分析网页内容的时候不可避免的要处理编码问题,因为从url读取的时候是字符流,网页上字符的编码是多样的,如果直接用java默认的字符集,十有八九会出现乱码。因此要在二进制流全部读取后,为其指定编码。

  需要说明的是,从url读取的二进制流中既有控制信息(html标签,css,js等),又有文本信息(我们在网页上看到的文字),又有二进制信息(图片等),因此如论我们指定何种编码方式,有些信息始终是无法解析成文字的。但是对于简单分析来说,只要将原来的文本信息解析出来就行了。

  如果想对得到的二进制文件作精确的分析,比如分别取出里面的图片、文字、样式等信息,恐怕需要不少工作,这个简单的小程序就做不到了。

  下面是程序代码:

  import java.io.File;

  import java.io.FileOutputStream;

  import java.io.InputStream;

  import java.io.OutputStream;

  import java.net.URL;

  import java.util.Arrays;

  public class MySpider {

  public static void main(String[] args) throws Exception{

  String rscount = new MySpider().grepAndgetRSCount("http://www.baidu.com/s?wd=北京雾霾");

  System.out.println("搜索结果的个数为:" + rscount);

  }

  private String grepAndgetRSCount(String urlstr) throws Exception{

  URL url = new URL(urlstr);

  InputStream inStm = url.openConnection().getInputStream();// 得到url对用的二进制流

  File outFile = new File("C:/grep.html");// 把得到的网页写入到这个文件

  if (!outFile.exists()) {

  outFile.createNewFile();

  }

  OutputStream outStm = new FileOutputStream(outFile);

  byte[] buffer = new byte[4096];

  int bytes_read;

  ByteArrayBuffer byteAbuf = new ByteArrayBuffer();

  while ((bytes_read = inStm.read(buffer)) != -1) {

  outStm.write(buffer, 0, bytes_read);// 把得到的二进制流写入到文件

  byteAbuf.append(buffer, bytes_read);// 缓存一份,供后面分析结果使用

  }

  inStm.close();

  outStm.close();

  String rscount = "-1";

  // 将得到的二进制流解析成文字,注意字符编码

  String rsStr = new String(byteAbuf.getBytes(), 0, byteAbuf.getByteslen(), "utf-8");

  if(rsStr.contains("百度为您找到相关结果约")){

  try{

  rscount = rsStr.split("百度为您找到相关结果约")[1].split("个")[0];

  }catch(Exception e){

  // do nothing

  }

  }

  return rscount;

  }

  }

  class ByteArrayBuffer{

  /**

  * 一个byte容器,存储读取的字节流

  */

  private byte bytes[];

  public byte[] getBytes() {

  return bytes;

  }

  public int getByteslen() {

  return byteslen;

  }

  private int byteslen;

  public ByteArrayBuffer(){

  bytes = new byte[1024];

  byteslen = 0;

  }

  public ByteArrayBuffer append(byte[] bytesAppend, int len){

  int freespace = bytes.length - byteslen;

  if(freespace < len){

  resize(len + byteslen);

  }

  System.arraycopy(bytesAppend, 0, bytes, byteslen, len);

  byteslen += len;

  return this;

  }

  private void resize(int newsize){

  int newsize1 = 1;

  while(newsize1 < newsize)

  newsize1 <<= 1;

  bytes = Arrays.copyOf(bytes, newsize1);

  }

  }