读书人

用httpclient仿照firefox发送http请求

发布时间: 2012-10-28 09:54:44 作者: rapoo

用httpclient模仿firefox发送http请求

?

?

最近需要做爬虫,研究了一下进行做http客户端的东东。

首先介绍一下http协议的工作大致原理,http协议是建立在tcp协议基础之上的一种应用层协议,tcp层的就不说了

首先web服务器在远程监听(默认80端口),由客户端发起请求,我们可以通过java提高的socket进行连接

?

??? Socket socket = new Socket("www.google.com", 80);

?

socket的构造有好几个方法,你可以这样最简单的方法构造,也可以指定本地地址(如果你有多个网卡或许有必要)和端口(像上面这样不指定则有操作系统随即分配)。

?

建立socket之后客户端将向服务器端发送数据,数据的内容就是请求的一些参数,第一行是status line,后面是http requester header, 如果是GET请求status line就是这样

?

??? GET http://wwww.google.com/ HTTP/1.1

?

这里GET后面的内容也可以是相对路径,那样的话就必须在后面加上Host参数了,参数怎么加呢,比如:

?

??? Host: www.google.com

??? User-Agent: Mozilla/5.0

??? Keep-Alive: 300

?

这样就给请求加了一些限制条件,但参数一般不是必须的,如果你请求的是相对路径,Host参数就少不了,应该像这样请求

?

?? GET / HTTP/1.1

?? Host: www.google.com

?

我们用java怎么实现呢,很简单啦,可以从socket中拿到输出流,把刚才的内容写出去就OK啦

?

?? String lineSep = System.getProperty("line.separator");

?? StringBuilder sb = new StringBuilder();

?? sb.append("GET / HTTP/1.1").append(lineSep)

?????? .append("Host: www.google.com");

?? OutputStream out = socket.getOutputStream();

?? DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(out));

?? dout.writeBytes(sb.toString());

?? dout.flush();

?

发送完数据后就要接收数据了,接收数据就是用socket拿到输入流,读数据了

?

?? InputStream in = socket.getInputStream();

?? DataInputStream din = new DataInputStream(BufferedInputStream(in));

?

拿到流之后爱怎么读就怎么读了,这样读的内容是不是单纯的网页内容,在网页内容的前面还包含了status line和http response header,这里的status line一般这样

?

?? HTTP/1.1 200 OK

?

表示协议,状态码,提示三部分,下面就header,包括一些参数,如

?

?? Date: Fri, 10 Apr 2009 03:32:50 GMT
?? Content-Length: 9697

?

以上介绍的方法比较麻烦,如果你要构建一个比较复杂的http客户端就很麻烦,想那些header都得自己解析,很烦。如果你像处理cookie就更复杂了,推荐大家使用Apache commons下的一个工具 httpclient,可以到http://hc.apache.org/downloads.cgi去下载,目前的版本是3.1,4.0还是测试版,最上面那个httpcore4.0 GA我就搞不懂了,估计是他们想用core代替client,高手请指教,那个我用过,结构和用法跟client完全不一样,很多网站请求不了,不推荐用。我用的是3.1。

httpclient功能很强大,使用也很广泛,用法也很简单,下载之后有文档,写的很好,参考一下就好了,那里的e文很简单,个别不认识的lingoes就是了。

?

这里我给一个我写的用于GET请求的,没有做POST,也没处理cookie,因为我暂时还没这需求,有需要的可以下载看看啦。


httprequester.zip

?

需要注意的是很多网站做了限制,阻止爬虫,你需要设置User-Agent参数为firefox的或者其他浏览器,我设置成了firefox

还有一个很重要的是编码问题,header里一般会说明charset(不是一定有的),但这个charset不一定是网页内容的编码。网页内容里也可以说明是什么编码(也不是一定有的),同样这样编码也不一定是真实的编码。最牛逼的办法是用firefox提供的一个组件,叫做jchardet,它可以猜想出字节的编码,效果应该是跟firefox的一样。我这里已经把这个jar包放进去了,用了这个组件来解码,jchardet解不了的才用header里的或者网页内容声明的,测试了很多网站,没有出现解码错误,效果不错。

?

这个附件了有所有依赖的jar,都放在lib里了,加到你的classpath里就可以用了,httprequester-1.0.jar是我写的,打包成二进制了,源代码在src里,javadoc在doc里。

2 楼 flyfox1982 2009-11-22 谢谢了,想学习下爬虫相关知识,能加你聊聊吗? tanyb02@163.com

读书人网 >软件架构设计

热点推荐