HttpClient 获取 Cookie 的一次踩坑实录

在使用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. 调用默认的解析方法

实现如下(URL就不公开了,已经隐去)

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

本文摘自:http://blog.jobbole.com/112469/?utm_source=group.jobbole.com&utm_medium=relatedArticles

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值