posts - 23,comments - 66,trackbacks - 0
by lostfire

最近一直试图用httpClient做点自动化的工作,不过现在看来并没有想象中的那么轻松。
实际上登录一个网站,访问某个特点的页面,发表一篇文章,上传一些文件,并不是一个简单的事情。
HttpClient的基本使用因为发布的代码中带有几个例子,应该算是不难掌握的事情。下面我说下我遇到的几个问题。

1,登陆验证图片问题
首先登录的时候网站如果不想你对它编程的化通常都会设计一个验证图片,这个技术现在已经如此的易于使用,以至于随便到哪里都能找到代码来直接使用。对于验证图片的,现在还苦于无计可施状态。

2,笨蛋Cookie问题:
如果你要发送多个cookie,其实可以这样发的:
state.addCookies (new Cookie[]{
            
new Cookie(" www.aaa.com","popped","yes","/",new Date(2006,12,8),false), 
            
new Cookie(" www.aaa.com","rtime","2","/",new Date(2006,12,8),false), 
            
new Cookie(" www.aaa.com","ltime","1149940477953","/",new Date(2006,12,8),false), 
            
new Cookie(" www.aaa.com ","cnzz02","1","/",new Date(2006,12,8),false),
        }
);

但是截包就会发现,httpclient会在header里构件多个cookie项,每一项只含有一个cookie,这同IE是不一样的。IE和Firefox会把所有的cookie打包成一个,然后在这个cookie里按照分号把每一项隔开,中间有个空格。
所以如果用httpclient,还想让cookie正常的话,请使用下面这种形式:

String cookies = "yes; rtime=2; ltime=1149940477953; cnzz02=1"
state.addCookie(
new Cookie("blog.aaa.com","poped",cookies,"/",new Date(2006,12,8),false)); 



3,编码问题:

httpClient处理编码并不像IE或FireFox那么智能,httpclient记不住上次会话的编码,这样如果默认不是ISO-8859-1的话,那都要在Content-Type里边指定,其实指定的方法也很简单。
本来要提交的是form,默认按照application/x-www-form-urlencoded来发送,在IE里边发送的话截包可以看到,报文中也就指定了这样一个Content-Type,但是人家IE已经把报文的内容按照会话的编码转换好了。而httpclient不行,它并不知道怎么转化,那么你没有设定转换的charset的话,它就按照Charset=ISO-8859-1转换了。这一点上Httpclient应该再改进一下,因为记住server发过来的页面编码是件很简单的事情。只要将类似于"Content-Type: text/html; charset=utf-8"这样的头保存一下状态就可以了。
为了弥补httpclient这一点的傻瓜表现,我们只好每次都手工设置一下喽:
postMethod.addRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");

4,上传文件问题:
 
httpClient并不能很好的模拟文件上传。
首先是对于文件类型的识别,IE可以做到按照文件类型分别选择不同的Content-type进行发送,而httpclient就需要我们自己设定,这样如果对一个目录进行自动化上传的话就必须知道该目录下所有文件的类型,以及对应的charset,然后再设置FilePart的时候逐一判断文件扩展名,以赋给不同的content-type和charset,对于一些网页编码是gb2312,而另外一些网页编码是utf-8则会更加麻烦。
其次是如果发送的multiPartPost报文中除了FilePart以外,还需要一些form中的其他input的信息,又是一件很麻烦的事情。刚开始的时候我以为像一般的PostMethod一样,使用PostMethod.addParameters()就可以了,后来才发现这个 MultiPartPost跟那个Post根本就是两个不同的Post。虽然从网页上看都是Form,且只是在input的类型上 MultiPartPost包含一个file类型的input,其他完全一样,但实际上在httpClient中是完全不同的两套方案。对于MultiPartPost而言,不能用addParameters(),而要使用


someMultiPartPost.setRequestEntity(
     
new MultipartRequestEntity( 
         
new Part[] { art1,part2,part3,part4}
                    someMultiPartPost.getParams())
);


这种形式。对于要上传的File,那么这些part就是FilePart对象,如果是跟随form的其他input,那么这些part就是 StringPart。这样发出去的报文才是:Content-Disposition: form-data; name="newFolderName"这种形式。


总结起来,其实也不能怪人家HttpClient,天下间哪有那么多容易做到的事情,尤其是面对Http这样一个说来不算简单的协议。
实际上像这种开源已久的东西,已经有了不少的文档,虽然有时候不太好找,但很多问题还是能够猜或者试出来,毕竟相对比较成熟,而且遵循这rfc来做的。就像我在水母上问问题,有人说的那样,世界上有什么能模拟的像IE一样呢,也不能拿IE的标准要求HttpClient。
我现在的感觉是要想用好HttpClient,或者类似的别的什么工具(其他我就不知道了,有知道类似工具的麻烦告诉我一声),其实还是要把协议吃透,这样一旦遇到什么问题,才知道问题出在哪里,否则就只有郁闷的份儿了。
昨天去Apache的网站,看到一个新的Project叫做HttpComponent从common里边脱离出来,包含了HttpCore, HttpClient,HttpAsync,HttpNIO,HttpCookie,HttpConn,看不出到底想做成什么样子,不过HttpCore 4.0 alpha2已经发布了,以后HttpClient用起来可能又有新的变化了。

一周的时间,用的不是很多,有说得不妥的地方,还请大家指正。
posted on 2006-06-15 00:12 rd2pm 阅读(9559) 评论(12)  编辑  收藏 所属分类: http tool

FeedBack:
# re: httpclient 3.0初步研究
2006-06-15 08:51 | Dedian
hehe, 我也想利用Httpclient做一些到名人的博克上抢沙发的事,可惜并不是那么简单。anyway,关注你的研究。  回复  更多评论
  
# re: httpclient 3.0初步研究
2006-06-15 15:59 | Compass
blogjava的验证码是放在cookie里面的,可以用httpclient来抢沙发  回复  更多评论
  
# re: httpclient 3.0初步研究
2006-06-16 00:59 | I like java
@Compass
blogjava有验证码么?  回复  更多评论
  
# re: httpclient 3.0初步研究
2006-06-16 10:37 | Compass
@I like java

匿名发表评论需要验证码  回复  更多评论
  
# re: httpclient 3.0初步研究
2006-06-16 16:00 | steeven
沙发和飞机是有关系的  回复  更多评论
  
# re: httpclient 3.0初步研究
2006-07-09 15:32 | pysh@163.com
验证码问题,可以找javaocr来解决。  回复  更多评论
  
# re: httpclient 3.0初步研究
2006-07-09 15:43 | pysh@163.com
用httpclient来get操作很简单,但应该注意把httpclient利用它提供的ConnectionManager管理起来。
用来post操作是一件麻烦的事情。

cookie基本上不是问题。设置兼容的CookiePolicy即可

post的值要全面,一般来说,把需要post的页面先get下来,把各个field的值 set到需要post的页面上会减轻很多工作。

但很多网站很刁难的进行了许多其他工作,逐个的分析太烦人的。如果您能对donews的blog利用httpclient维护。欢迎赐教。





  回复  更多评论
  
# re: httpclient 3.0初步研究
2006-07-09 18:21 | lostfire
@pysh@163.com
我就是对donews做了一个小实验,发现上边提到的cookie的问题的,不过后来采用我上边提到的urgly的方法已经可以对donews做发文操作了。
这两天在做另外一个实验的时候,发现这个Cookie的问题并不总是会出现,但会有其他的问题,可能是我对.net做网站的方法了解太少的原因吧。  回复  更多评论
  
# re: httpclient 3.0初步研究
2006-07-31 15:09 | air
我想請教一下, 當 get 所得回來的數據含有 multi-part 時, 甚至是有多個檔案的時候, 要怎樣去區分?
@pysh@163.com
  回复  更多评论
  
# re: httpclient 3.0初步研究
2006-08-01 16:37 | lostfire
@air

据我所知,multi-part是post的一种方式,我并没有遇到过get到multi-part的情况,可以提供一个网址,我也想看看get到multi-part是一种什么情况。  回复  更多评论
  
# re: httpclient 3.0初步研究
2006-11-10 15:58 | guolp
哥们,验证码的问题有解决方案没有,能不能发布出来以供学习呀
或者发邮件也可以
mail:mlssoft@126.com  回复  更多评论
  
# re: httpclient 3.0初步研究
2007-11-03 14:06 | 中华信鸽
验证码可不好过。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: