如何抓取网页
一、URL与URI
1、URI
在电脑术语中,统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作。URI由包括确定语法和相关协议的方案所定义。Web上可用的每种资源 -HTML文档、图像、视频片段、程序等 - 由一个通用资源标识符(Uniform Resource Identifier, 简称"URI")进行定位。
例:存放资源的自身的名称,由路径表示。参考下面的URI,它符合当前的RFC4395规范:协议名称://域名.根域名/目录/文件名.后缀。例如http://b.c/d/e.f (假设b.c是一个可用的域名,e.f是一个标准的文件)。这个URI是这样的:这是一个可通过HTTP协议访问的资源,位于主机b.c上,通过URI中的字符串“/d”访问主机上的“d”文件夹,通过“e.f”请求访问主机上“/d/e.f”这个文件。
2、URL
统一资源定位符(Uniform Resource Locator,URL)是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
基本URL包含模式(或称协议)、服务器名称(或IP地址)、路径和文件名,如“协议://授权/路径?查询”。完整的、带有授权部分的普通统一资源标志符语法看上去如下:协议://用户名:密码@子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值#标志。
二、通过指定的URL抓取网页
网页抓取,就是要将URL地址中指定的网络资源以流的形式读取出来,保存在本地。在这里我们使用Java语言。Java语言将网络资源看作是一种文件,因此访问方便。它将请求与相应封装为流。
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。我们引入HttpClient.jar包。
//首先创建一个客户端,相当于打开一个浏览器:
HttpClient httpclient = new HttpClient();
接下来有两种方式对URL进行请求。
1、get方法
//打开链接”http//QengHo.com/cn”
GetMethod getMethod = New GetMethod(“http//QengHo.com.cn”);
//回车,获得响应状态
Int statusCode = httpclient.excuteMethod(getMethod);
//查看命中情况,可以获得的东西还有很多,如head、cookie等
System.out.printIn(“response” = + getMethod.getResponseBodyAsString);
//释放
getMethod.releaseConnection();
2、post方法
//得到post方法
PostMethod PostMethod = new PostMethod(“http//www.QengHo.com.cn”);
//使用数组来传递参数
NameValuePair[] postDate = new NameValuePair[2];
//设置参数
postDate[0] = new NameValuePair(“武器”,”枪”);
postDate[1] = new NameValuePair(“什么枪”,”神枪”);
postMethod.addParameters(postDate);
//回车,获得响应状态
Int statusCode = httpclient.excuteMethod(getMethod);
//查看命中情况,可以获得的东西还有很多,如head、cookie等
System.out.printIn(“response” = + getMethod.getResponseBodyAsString);
//释放
getMethod.releaseConnection();
使用post方法可以设置参数;get方法需要把URL中传递给服务器。由于URL长度有限,因此参数传递会收到限制。
三、Java抓取网页举例
public class RetrivePage {
Private static HttpClient httpclient = new HttpClient();
//设置代理服务器
Static
{
//设置代理服务器的ip和端口
httpClient.gethostconfiguration().setproxy(“172.17.18.84”,8080);
}
Public static boolean downloadpage(string.path) throws HttpException,
IOException {
Inputstream input = null;
Outputstream output = null;
PostMethod PostMethod = new PostMethod(Path);
NameValuePair[] postDate = new NameValuePair[2];
postDate[0] = new NameValuePair(“name”,”lietu”);
postDate[1] = new NameValuePair(“password”,”******”);
postMethod.addParameters(postDate);
Int statusCode = httpclient.excuteMethod(getMethod);
//针对状态码进行处理,简单起见,只处理返回值为200的状态码
If (statusCode = HttpStatus.SC_OK){
Input = postMethod.getMethod.getResponseBodyAsString();
//得到文件名
String filename = path.substring(path.lastIdxOf(‘/’)+1);
//获得文件输出名
Output = new FileOutputStream(filename);
//输出到文件
Int tempByte = -1;
While((tempByte = input.read() )> 0) {
Output.write(tempByte);
}
//关闭输入输出流
If(input != null){
Input.close();
}
If(output != null){
output.close();
}
Return true;
}
Return fales;
}
/*测试代码*/
Public static void main (string[] args) {
//抓取lietu首页,输出
Try {
RetrivePage.downloadPage(“http//www.lietu.com/”);
}
Catch (HttpExceptiong e) {
//todo auto-generated catch block
e.printStackTrace();
}
Catch (IOException e) {
e.printStackTrace();
}
}
}
四、处理HTTP状态码
Int statusCode = httpclient.excuteMethod(getMethod);
该语句获得网页的状态码,状态码如下图所示
当状态返回值为5XX时,使用丢弃操作。
当状态返回值为3XX时,使用转向操作。
If (statusCode = = HttpStatus.CK_OK) {
Input = postMethod.getResponseBodyAsStream();
//得到文件名
String filename = path.substring(path.lastIndexOf(‘/’)+1);
//获得输出流文件
Output = new FileOutpurStream(filename);
//输出到文件
Int tempByte = -1;
While((tempByte = input.read()) > 0) {
Output.write(tempByte);
}
}