Java网络编程——Cookie & Session

cookie

前面我们学习 Okhttp3 库可以调用API、抓取网页、下载文件。但是这些操作都是不要求登录的,如果 API、网页、文件等内容要求登录才能访问,就需要学习新的 cookie 相关的知识了。

下面以豆瓣为例,使用 Java 程序读取“我的豆瓣”页面内容,在此过程中熟悉运用 cookie

所谓 cookie ,是存储在客户端浏览器中的一段文本内容。以 key=value (数据名称、数据值)的格式存储一条数据;多条数据之间用分号 ; (英文半角)分开。由于各种浏览器都对 cookie 大小和数量有限制,所以 cookie 目前的核心功能是存储登录数据;额外可以存储一些小数据,比如 是否登录=true;昵称=张三 这样的内容不大的数据。

InternetExplorer 限制 cookie 为每个域名 50 个,上限 4095 个字节。Firefox 每个域名 cookie 限制为 50 个,上限 4097 个字节。每种浏览器略有异同,但肯定都有限制。

1.前期准备

在浏览器输入 https://www.douban.com/mine 打开“我的豆瓣”页面。这个页面是必须登录的。

豆瓣登录

登录完成以后,可以正确看到“我的豆瓣”页面了。

我的豆瓣

注意:登录信息是存放在 cookie 里的

所以,必须先找到登录后的 cookie,这是完成 Java 程序的重要的前提条件。

2.找到 cookie

打开谷歌浏览器的开发者工具(使用谷歌浏览器),切换到 Network 菜单项,如下图所示第一步:

对谷歌开发者工具不熟悉的,可以点击查看 使用教程

豆瓣点赞登录

如果没有 mine ,就选第一个跟浏览器地址栏相同的 URL 请求

按照图中所示的四个步骤,把 cookie 的值(Cookie: 后的内容哦,不包括 Cookie:)拷贝下来,放入一个 cookie.txt 文件中。

cookie 的内容很长,而且看不懂。因为 cookie 中除了登录信息,还能放其它信息,大多是加密过的。但没关系,这些信息是给计算机看的。

我们需要编码把 cookie 信息字符串转换为 Map 类型的数据。

3.编码实现

实际上,程序我们前面练习过,就是使用 Okhttp3 库完成 get 请求而已。

会用到前面的知识,特别是第 4 章第 12 节的内容,不熟悉的同学复习一下。

上图中可以看到,浏览器在发送请求的时候,自动带上了 HostUser-Agent 内容哦。

这样,所需的数据都已识别完毕,我们先看一下演示程序。系统提供了一个工具类,用于从 cookie.txt 文件读取内容。

代码演示

大家可以看到,Cookie 也是存放在 header 中的哦。

session

上节课使用了谷歌浏览器的开发者工具抓取到了登录的 cookie ,然后使用程序完成登录。

cookie 的弊端是,cookie 是存放在客户端浏览器的,而且是临时的,登录后还想以登录状态与服务器通讯,就比较麻烦。

这就需要在程序中使用 Session 对象来解决这个问题。下面我们通过模拟登录时光网来学会如何应用 Session 对象。

1.时光网登录

浏览器中输入http://www.mtime.com/ 打开时光网,点击右上角的登录按钮;

如果没有看到输入框,可以点击角落电脑图标切换:

时光网1

弹出登录对话框。

时光网1

或者直接 点此打开注册与登录页面,并点击“会员登录”

时光网2

如果没有注册的,先注册,再退出登录,并重复此步骤。

如果遇到电脑无法注册时光网的情况,麻烦下载时光网APP,进行注册。

2.收集信息

然后打开谷歌浏览器的开发者工具,如图所示,Preserve log 必须勾选。

对谷歌开发者工具不熟悉的,可以点击查看 使用教程

关键点

输入用户名和密码后,在右侧抓取到的网络请求中,找到登录请求 API

https://front-gateway.mtime.com/user/user/login.api

时光网3

新版浏览器可能有一点不同

在“标头”后面多了一个“载荷”(Payload)的小菜单。

时光网3

切换到小菜单可以看到密码:

时光网3

时光网改版了,所以谷歌浏览器的开发者工具里,输入框输入login进行过滤哦。

由于改版,视频中有些细节是旧的,例如登录页面是旧版的。但是没关系,操作过程是一样的。

需要收集的关键信息包括:

  1. 登录地址
  2. 执行方式(GET/POST)
  3. HOST
  4. Referer
  5. User-Agent
  6. 表单数据,数据名称和数据值

由于每个网站登录相关的信息都不一样,所以必须在手动登录的过程中收集信息。大家学会这个方法,就可以模拟其它网站登录。

3.编码实现

提醒

  // 用 CookieJar 实现 cookie 的存储,便于登录后请求其它 URL 可以复用
  private static final OkHttpClient okHttpClient = new OkHttpClient.Builder()
      .cookieJar(new CookieJar() {
        private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
          cookieStore.put("mtime.com", cookies);
          System.out.println("[saveFromResponse]url.host()=" + url.host());
        }

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
          System.out.println("[loadForRequest]url.host()=" + url.host());
          List<Cookie> cookies = cookieStore.get("mtime.com");
          return cookies != null ? cookies : new ArrayList<>();
        }
      })
      .build();
  • CookieJar 是接口(interface),而 不是 类(class)。演示代码中:

    new CookieJar() {......}
    

    是匿名类。关于匿名类,匿名类的概念感兴趣可以阅读匿名类知识点

  • 对表单提交不熟悉的同学,需要复习本课程的第二章第三节。

HashMap

cookieStore 的类型是 HashMap ,相当于一个登录信息的 集合容器 ,可以用来不存 不同域名登录信息(cookie) 。

程序具备扩展性

HashMap 是用法,在前面的《Java 基础强化》课程已经讲过,大家可以复习一下。

  • cookieStore.put("mtime.com", cookies); 就是把当前爬取到的时光网的登录信息存储起来。
  • cookieStore.get("mtime.com"); 就是把当前爬取到的时光网的登录信息从容器中拿出来。

当然这个容器是临时的,本质上是存入计算机内存,当前程序关闭掉,信息就消失了

复用session

上节课我们完成了模拟登录。模拟登录的目的,还是为了能够调用必须登录的API、或请求必须登录的网页等。

其实,为我们只需要在上节课登录成功的基础上,使用 session 对象再次发出请求即可完成这些必须登录的请求。

我们先来看案例演示:

请求“个人设置”页面(http://my.mtime.com/personal/personInfo):

实现

不知道大家注意没有,在上一节中,我们把 OkHttpClient 对象进行重构,不再定义为 postContent() 方法的变量。

而是改为类变量:private static final OkHttpClient okHttpClient ,目的就是在整个类中,使用同一个 okHttpClient 执行 HTTP 请求,提升效率。重构在本节课就派上用场了。

分析执行两次请求的过程,实际上过程是类似的,区别是 Request 不同,所以,又做了一次重构,把真正执行的过程封装成一个方法:doExcute ,被其它 postContent()getContent() 方法调用。

这么做就是抽象的过程,目的是减少重复代码,提高可阅读性和可维护性。重构会伴随我们整个编程的生涯。请大家认真体会这个过程,还可以动手试一下,如果不重构,代码会是什么样的?

小知识点

  • static 表示类变量,意味着无论 new 出多少个 PageLoginer 对象,PageLoginer.okHttpClient 都只有一个。
  • final 表示 okHttpClient 一旦第一次 new 出对象后,不能再次 new 新对象。
  • 18
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值