引言
URLConnection 是 JDK 自带的一个抽象类,其代表应用程序和 URL 之间的通信链接。在网络爬虫中,我们可以使用 URLConnection 请求一个 URL 地址,然后获取流信息,通过对流信息的操作,可获得请求到的实体内容。在本篇主要介绍以下内容:
- 如何创建 URLConnection 对象;
- URLConnection 获取数据内容;
- Get() 请求操作;
- Post() 请求操作;
- 请求头的设置;
- 超时的设置;
- 代理的设置。
另外,本篇所涉及的代码均已上传到了 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 ) { //如果响应状态码为200BufferedReader 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()
参考内容
- 类 URLConnection
- 通过 HttpURLConnection 模拟 POST 表单提交