`
tuoxie007
  • 浏览: 160214 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用httpclient模仿firefox发送http请求

    博客分类:
  • Java
阅读更多

 

 

最近需要做爬虫,研究了一下进行做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
0
分享到:
评论
2 楼 flyfox1982 2009-11-22  
谢谢了,想学习下爬虫相关知识,能加你聊聊吗? tanyb02@163.com
1 楼 Hooopo 2009-05-02  

相关推荐

Global site tag (gtag.js) - Google Analytics