网页内容获取工具 URLConnection

引言

URLConnection 是 JDK 自带的一个抽象类,其代表应用程序和 URL 之间的通信链接。在网络爬虫中,我们可以使用 URLConnection 请求一个 URL 地址,然后获取流信息,通过对流信息的操作,可获得请求到的实体内容。在本篇主要介绍以下内容:

  1. 如何创建 URLConnection 对象;
  2. URLConnection 获取数据内容;
  3. Get() 请求操作;
  4. Post() 请求操作;
  5. 请求头的设置;
  6. 超时的设置;
  7. 代理的设置。

另外,本篇所涉及的代码均已上传到了 Github 上,读者可以自行下载学习。

URLConnection 的使用

创建 URLConnection 对象

使用 URLConnection 时,我们无法直接实例化对象,但可以通过在 URL 上调用 openConnection() 方法创建一个连接对象,URL 表示此连接要在互联网上打开的远程对象。其使用方法如下:

URL url = new URL("http://www.w3school.com.cn/b.asp");
URLConnection conn = url.openConnection(); 

此处的 conn 对象实际上是根据 URL 的请求协议生成的 URLConnection 类。

获取数据内容

要获取URLConnection 请求到的内容,需通过流操作的方式。在 openConnection() 方法执行之后,通过 getInputStream() 获取输入流,之后采用 BufferedReader 读取输入流信息。

基于下面的程序,便可成功输入我们请求到的网页信息(http://www.w3school.com.cn/b.asp)。

InputStream in=conn.getInputStream();
// 定义BufferedReader输入流来读取URL的响应  
BufferedReader reader = new BufferedReader(  
        new InputStreamReader(in));  
String line; 
String html = "";  //这里的内容是html
while ((line = reader.readLine()) != null) {  
    html +=  line;  
}  
System.out.println(html);

GET 请求

在 URLConnection 中,我们可以利用其子类 HttpURLConnection 设置请求方法,如 GET 请求。操作程序如下:

//初始化URL
URL url = new URL("http://www.w3school.com.cn/b.asp");
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //使用URLConnection的子类HttpURLConnection
// 允许Input
conn.setDoInput(true);   //将此 URLConnection 的 doInput 字段的值设置为true
conn.setRequestMethod("GET");  //设置请求的方法GET
//conn.setRequestMethod("POST"); //注意该网页只能使用GET请求
conn.connect();  //建立实际连接操作
int statusCode = conn.getResponseCode(); //获取响应状态码
String responseBody = null;
if (HttpURLConnection.HTTP_OK == statusCode ) {  //如果响应状态码为200
    BufferedReader bufferedReader = new BufferedReader(
            new InputStreamReader(conn.getInputStream(), "GBK"));  // 定义BufferedReader输入流来读取URL的响应 ,这里设置编码
    //读取内容
    String readLine = null;
    StringBuffer response = new StringBuffer();
    while (null != (readLine = bufferedReader.readLine())) {
        response.append(readLine);
    }

    bufferedReader.close();
    responseBody = response.toString();
}
System.out.println(responseBody);

在上述程序中,我们设置了 setDoInput(true) 表示 URL 连接可用于输入。子类 HttpURLConnection 建立实际连接需要使用 connect() 方法。基于 getResponseCode() 方法可以获取连接响应的状态码,如果该状态码为200,则将响应流读取出来。

POST 请求

使用 HttpURLConnection 也可以提交 POST 请求,例如对表单进行操作。本小节我以一个简单的表单请求为例,这里我们选择了中国邮政快件查询网站。为了获得 POST 方法需要提交的参数,我对该网站进行了抓包,抓包结果如下:

从抓包结果中,可以看到需要提交的参数有三个,但真实输入参数 wen 以及 action 这两个参数便可以请求到数据了。

wen:EH629625211CS action:ajax rnd:0.13662514160225325

具体程序如下:

//Post表单需要提交的参数
String wen = "EH629625211CS";
String action = "ajax";
//初始化URL
URL url = new URL("http://www.kd185.com/ems.php");
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //使用URLConnection的子类HttpURLConnection
// //允许Input、Output,不使用Cache
conn.setDoOutput(true);  //将此 URLConnection 的 doOutput 字段的值设置为true
conn.setDoInput(true);   //将此 URLConnection 的 doInput 字段的值设置为true
conn.setUseCaches(false);   // 将此 URLConnection 的 useCaches 字段的值设置为false
conn.setRequestMethod("POST"); //Post提交参数
StringBuffer params = new StringBuffer();  
// 表单参数拼接
params.append("wen").append("=").append(wen).append("&")
        .append("action").append("=").append(action);
byte[] bypes = params.toString().getBytes();
conn.getOutputStream().write(bypes);// 在连接中添加参数
BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(conn.getInputStream(), "utf-8"));  // 定义BufferedReader输入流来读取URL的响应 ,这里设置编码 
String line; 
String html = "";
while ((line = bufferedReader.readLine()) != null) {  
    html +=  line;  
}  
System.out.println(html);

在 POST 请求程序中,需要设置 setDoOutput() 为 True。该程序能够成功获取服务器返回的数据,如下图所示:

这里写图片描述

请求头的设置

在 URLConnection 以及 HttpURLConnection 中,我们可以使 setRequestProperty(key,value) 的形式设置请求头信息。例如,以下案例:

//初始化URL
URL url = new URL("http://www.w3school.com.cn/b.asp");
URLConnection conn =  url.openConnection(); //使用URLConnection
//添加请求头信息
conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");  
conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9"); 
conn.setRequestProperty("Host", "www.w3school.com.cn"); 
conn.setRequestProperty("Cache-Control", "max-age=0"); 
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36"); 
conn.connect();  //实际连接操作

如若是 HttpURLConnection 设置请求头,只需将上面代码中的 URLConnection conn = url.openConnection() 修改为:

HttpURLConnection conn = (HttpURLConnection) url.openConnection()

超时设置

超时设置,防止网络异常时,可能会导致程序僵死而不继续往下执行的情况。在 URLConnection 以及 HttpURLConnection 中,设置超时包括连接超时和读取超时,其操作如下:

URLConnection conn =  url.openConnection();
// HttpURLConnection conn = (HttpURLConnection) url.openConnection()
conn.setConnectTimeout(30000); //连接超时 单位毫秒 
conn.setReadTimeout(30000);   //读取超时 单位毫秒

代理的设置

在 URLConnection 以及 HttpURLConnection 中,我们可以使用 Proxy 进行设置代理,关于设置代理的作用,读者可以参考《第05课:网页内容获取工具 HttpClient 》。以下程序为 URLConnection 设置代理:

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("171.97.67.160", 3128));  //设置代理
URL url = new URL("http://www.w3school.com.cn/b.asp");  
RLConnection conn = url.openConnection(proxy);  //以代理的方式建立连接
conn.connect(); //建立实体连接
BufferedReader bufferedReader = new BufferedReader(
    new InputStreamReader(conn.getInputStream(), "gbk"));  // 定义BufferedReader输入流来读取URL的响应 ,这里设置编码 
String line; 
String html = "";
while ((line = bufferedReader.readLine()) != null) {  
    html +=  line;  
}  
System.out.println(html);

同样,若使用 HttpURLConnection 设置代理,只需将上面代码中的 URLConnection conn = url.openConnection() 修改为:

HttpURLConnection conn = (HttpURLConnection) url.openConnection()

参考内容

  1. 类 URLConnection
  2. 通过 HttpURLConnection 模拟 POST 表单提交

猜你喜欢

转载自blog.csdn.net/qq_37969990/article/details/81630609
今日推荐