有些网站,我们通过浏览器是无法直接访问的,这并不能说明这些网站中的资源是不存在的。这时,如果访问的目标网站支持代理访问,可以考虑使用代理来访问这些网站的资源。
使用代理访问的基本原理简述如下:
首先,要知道,我们通过浏览器访问某个网站的时候,是先请求该网站的Web服务器,Web服务器负责负责请求网站的后台数据库服务器,获得请求的数据,然后整合这些数据和网页等资源,响应客户端浏览器的请求。
代理服务器是位于客户端和Web服务器之间一个中间服务器。我们通过使用浏览器中配置的相应代理,将请求发送到代理服务器,代理服务器代理我们客户端去请求Web服务器,将请求到的响应资源再次响应我们客户端,同时缓存到代理服务器上,以备下次客户端请求代理服务器的时候,直接从代理服务器上取得要请求的资源,而无需再次请求网站的Web服务器,提高了响应速度。
HttpCliemt是一个比较容易配置的工具,你可以直接给定一个代理IP地址和端口,如果需要登录的话,还需要给出一个登录账户(用户名和密码)。网上可以搜索到很多免费的匿名代理,通过这些代理可以访问一些无法通过浏览器直接访问到的网站。
下面给出一个简单的使用HttpClient,配置匿名代理访问的例子:
package org.shirdrn.proxy;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.GetMethod;
public class MyProxy {
private HttpClient client;
private HttpMethodBase method;
private byte[] binaryData;
private Header[] headers; // 响应头信息
public MyProxy() {
this.client = new HttpClient(); // 创建一个HttpClient实例
}
// 配置客户端请求参数
public void config(String proxyHost, int proxyPort, String url) throws URIException, NullPointerException {
this.method = new GetMethod();
HostConfiguration hostConfiguration = new HostConfiguration();
URI uri = new URI(url, true);
hostConfiguration.setHost(uri);
this.client.setHostConfiguration(hostConfiguration);
this.client.getHostConfiguration().setProxy(proxyHost, proxyPort); // 配置代理IP和端口
}
public void execute() throws HttpException, IOException { // 执行请求
int status = this.client.executeMethod(this.method);
if(status == HttpStatus.SC_OK) {
this.headers = this.method.getResponseHeaders();
InputStream stream = this.method.getResponseBodyAsStream();
if(stream != null) {
ByteArrayOutputStream data = new ByteArrayOutputStream();
int readCount = 0;
byte[] buffer = new byte[512];
while((readCount=stream.read(buffer))>0) {
data.write(buffer);
}
this.binaryData = data.toByteArray();
}
}
}
private void printResponseHeaders() { // 打印响应头信息
for(Header header : this.headers) {
System.out.println(header.getName() + " : " + header.getValue());
}
}
private void printStringData(String encoding) throws UnsupportedEncodingException { // 简单编码并打印响应字符串数据
if(encoding == null) {
encoding = "utf-8";
}
String data = new String(this.binaryData, encoding);
System.out.println(data);
}
public static void main(String[] args) throws Exception {
String url = http://xx.org/; // 无法通过浏览直接器访问,你可以找到一个需要使用代理访问的网站
MyProxy mp = new MyProxy();
String proxyHost = "130.136.254.21";
int proxyPort = 3124;
mp.config(proxyHost, proxyPort, url);
mp.execute();
mp.printStringData(null);
mp.printResponseHeaders();
}
}
执行主方法,就可以看到,通过匿名代理请求到的网站的网页源代码。
爬虫在采集数据的时候,尤其是有些论坛的数据,可能需要通过配置代理来完成对指定网站资源的爬行,这样不至于爬虫在工作的过程中由于无法之间建立到目标网站的Http连接而多次重试,最终还是无法取得网页资源。
详细出处参考:http://www.91linux.com/html/article/program/jsp/20090802/17732.html