<-!-FA27NTk-> <-!-FA27NTk-> HttpClient获取cookie时出现Invalid ‘expires’ attribute错误的解决方法 – FullStack Yang
HttpClient获取cookie时出现Invalid ‘expires’ attribute错误的解决方法

HttpClient获取cookie时出现Invalid ‘expires’ attribute错误的解决方法

在使用HttpClient进行抓取一些网页的时候,经常会保留从服务器端发回的Cookie信息,以便发起需要这些Cookie的请求。大多数情况下,我们使用内置的cookie策略,便能够方便直接地获取这些cookie。

下面的一小段代码,就是访问http://www.baidu.com,并获取对应的cookie:

打印结果

但是也有一些网站返回的cookie并不一定完全符合规范,例如下面这个例子,从打印出的header中可以看到,这个cookie中的Expires属性是时间戳形式,并不符合标准的时间格式,因此,httpclient对于cookie的处理失效,最终无法获取到cookie,并且发出了一条警告信息:“Invalid ‘expires’ attribute: 1505204523”。

虽然我们可以使用header的数据,重新构造一个cookie出来,也有很多人确实也是这么做的,但这种方法不够优雅,那么如何解决这个问题?网上相关的资料又很少,所以就只能先从官方文档入手。
在官方文档3.4小节custom cookie policy中讲到允许自定义的cookie策略,自定义的方法是实现CookieSpec接口,并通过创建CookieSpecProvider的实现,来完成在httpclient中的初始化和注册策略实例的工作。好了,关键的线索在于CookieSpec接口,我们来看一下它的源码:

在源码中我们发现了一个parse方法,从注释中可以知道,正是这个方法,将Set-Cookie的header信息解析为Cookie对象,自然地再看一下在httplcient中的默认实现DefaultCookieSpec,限于篇幅,源码就不贴了。在默认的实现中,DefaultCookieSpec主要的工作是判断header中Cookie规范的类型,然后再调用具体的某一个实现。像上述这种Cookie,最终是交由NetscapeDraftSpec的实例来做解析,而在NetscapeDraftSpec的源码中,定义了对应expires时间格式为“EEE, dd-MMM-yy HH:mm:ss z”

到这里已经比较清楚了,我们只需要将Cookie中expires的时间转换为正确的格式,然后再送入默认的解析器就可以了。

解决方法:

1.自定义一个CookieSpec类,继承DefaultCookieSpec

2.重写parser方法

3.将Cookie中的expires转换为正确的时间格式

4.调用默认的解析方法

实现如下:

再次运行,便可顺利地打印出正确的结果,完美!

Loading Likes...

说点什么

您将是第一位评论人!

提醒
avatar
wpDiscuz