一个简单的java爬虫

试了一下用Java写爬虫,确实不如python写起来简单。

URLConnection类

转自:URLConnection类,HttpURLConnection类的使用和总结
抽象类 URLConnection 是所有类的超类,它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源。URLConnection 基于Http协议。通常,创建一个到 URL 的连接需要几个步骤:

  1. 通过在 URL 上调用 openConnection 方法创建连接对象。
  2. 处理设置参数和一般请求属性。
  3. 使用 connect 方法建立到远程对象的实际连接。
  4. 远程对象变为可用。远程对象的头字段和内容变为可访问。

-URLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。
无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。

在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重,
对connection对象的处理设置参数和一般请求属性和写入提交数据都必须要在connect()函数执行之前完成。对outputStream的写提交数据操作,必须要在inputStream的读操作之前。这些顺序实际上是由http请求的格式决定的。

http请求实际上由两部分组成,一个是http头,所有关于此次http请求的配置都在http头里面定义,一个是正文content。connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,就必须把所有的配置准备好。

在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)都是没有意义的了,执行这些操作会导致异常的发生。

HttpURLConnection类是支持 HTTP 特定功能的 URLConnection。每个 HttpURLConnection 实例都可用于生成单个请求,但是其他实例可以透明地共享连接到 HTTP 服务器的基础网络。请求后在 HttpURLConnection 的 InputStream 或 OutputStream 上调用 close() 方法可以释放与此实例关联的网络资源,但对共享的持久连接没有任何影响。如果在调用 disconnect() 时持久连接空闲,则可能关闭基础套接字。

URLConnection 是所有类的超类,它代表应用程序和 URL 之间的通信链接。该类的实例可以用来对由 URL 引用的资源进行读取和写入操作。

模式匹配Pattern类和Matcher类

爬取网站的图片,使用正则表达式从网页上匹配出图片的url

java.util.regex.Pattern和java.util.regex.Matcher用于模式匹配的类,模式对象封装了正则表达式。Matcher对象方法则主要针对匹配结果进行处理,下面用代码段示例说明:

String regex = "[a-z] at";
String str = "a fat cat and a rat were eating oat in the vat."
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
while(m.find()){
String s = m.group();
System.out.println(s);
}

关于pattern类和Matcher类有篇博客写的不错。
链接:JAVA正则表达式:Pattern类与Matcher类详解

下面是爬虫的代码:

package sp;
import java.io.*;
import java.net.*;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class spider {
	
	public static void main(String[] args) {
		String address ="http://www.netbian.com/index.htm";
		System.out.println("爬取http://www.netbian.com图片");		
		System.out.println("图片将保存至d:/java/picture");
		System.out.println("请输入从第几页开始爬取:");
		
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		System.out.println("爬取页数:");
		int m = scanner.nextInt();
		if (n <1) {
			System.out.println("页码小于1");
			System.exit(0);
		}else if(n > 1) {
			String snum = String.valueOf(n);
			 address = "http://www.netbian.com/index_"+snum+".htm";
		}
		
		for(;m>=1;m--) {
			String h = getHtm(address);
			//提取图片url
			Pattern imgpattern=Pattern.compile("http://img\\.netbian\\.com/file/.*?\\.jpg");
			Matcher imgmatcher=imgpattern.matcher(h);
			while (imgmatcher.find()){
        	
				String imgString=imgmatcher.group();
				String[]  strs=imgString.split("/");
				String name = strs[strs.length-1];
				String path = "d:/java/picture/"+name;
				downloadPicture(imgString,path);
				//更新下一页address
				String snum = String.valueOf(n+1);
				 address = "http://www.netbian.com/index_"+snum+".htm";
			}
		}
	}
	
	private static String getHtm(String address){
        HttpURLConnection conn = null;
        URL url = null;
        InputStream in = null;
        BufferedReader reader = null;
        StringBuffer stringBuffer = null;
        try {
            url = new URL(address);
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setDoInput(true);
            conn.connect();
            in = conn.getInputStream();
            reader = new BufferedReader(new      InputStreamReader(in));
            stringBuffer = new StringBuffer();
            String line = null;
            while((line = reader.readLine()) != null){
                stringBuffer.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            conn.disconnect();
            try {
                in.close();
                reader.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return stringBuffer.toString();
    }
	
	private static void downloadPicture(String imageurl,String path) {
 	   try {
		URL url = new URL(imageurl);
		DataInputStream dataInputStream = new DataInputStream(url.openStream());
		 
        FileOutputStream fileOutputStream = new FileOutputStream(new File(path));
        ByteArrayOutputStream output = new ByteArrayOutputStream();

        byte[] buffer = new byte[1024];
        int length;

        while ((length = dataInputStream.read(buffer)) > 0) {
            output.write(buffer, 0, length);
            System.out.println(imageurl);
        }
        fileOutputStream.write(output.toByteArray());
        dataInputStream.close();
        fileOutputStream.close();

		
 	   } catch (Exception e) {
 		   // TODO Auto-generated catch block
 		   e.printStackTrace();
 	   }
 	   
    }
}

一个简单的python爬虫

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值