记录一次 Selenium WebDriver 无法正常加载 www.xxx.com 域名 Cookie 文件的解决办法

本贴最后更新于 2125 天前,其中的信息可能已经物是人非

具体问题为,在使用 WebDriver 正常登录网址后,进行了 Cookie 保存,但在下次自动反序列化加载 Cookie 时发现无法正常加载,导致每次需要重新登录验证,目前采用了一种曲线救国的方式,在序列化 Cookie 时调整域名为 xxx.com,具体方案如下。

具体问题大家也可以参见:Add cookie exception when dot exists before domain name

首先,在成功登录后序列化 Cookie 时:

/** * 序列化CookieStore * @param driver WebDriver * @param cookieFile 序列化地址 * @return 是否序列化成功 */ public static boolean saveCookies(WebDriver driver, String cookieFile){ try{ Options options = driver.manage(); Set<Cookie> cookieSet = options.getCookies(); CookieStore cookieStore = CookieUtils.driverCookie2HttpCookie(cookieSet); return ObjectUtils.serializeFile(cookieStore, cookieFile); }catch(Exception e){ e.printStackTrace(); return false; } }
/** * 将获取的DriverCookie值转换为HttpCookie * @param driver WebDriver * @return CookieStore */ public static CookieStore driverCookie2HttpCookie(Set<org.openqa.selenium.Cookie> cookies) { CookieStore store = new BasicCookieStore(); for (org.openqa.selenium.Cookie cookie : cookies) { BasicClientCookie bcc = new BasicClientCookie(cookie.getName(), cookie.getValue()); // log.debug("[" + cookie.getName() + "]=[" + cookie.getValue() + "]" + cookie.getDomain() == null ? "" : cookie.getDomain()); // 整理Cookie,将www去掉,否则Driver在addCookies时将会自动在前面加.,即www.abc.com变成.www.abc.com,从而无法使用 String domain = cookie.getDomain(); bcc.setDomain(StringUtils.isEmpty(domain) ? null : domain.startWiths("www") ? domain.substring(3) : domain); bcc.setPath(cookie.getPath().equals("//") ? "/" : cookie.getPath()); bcc.setExpiryDate(cookie.getExpiry()); store.addCookie(bcc); } return store; }

然后就可以在下次加载 WebDriver 时正常加载 Cookie 了

/** * 给指定的URL填充Cookie * @param url 要加载的地址 */ protected void addCookies(String url) { driver.get(url); if(null != cookieStore){ driver.addCookies(cookieStore); driver.refresh(); driver.waitPageLoad(); } }
/** * 给Driver增加Cookie * @param driver * @return */ public void addCookies(CookieStore cookieStore) { Options options = driver.manage(); List<Cookie> cookieList = CookieUtils.httpCookie2DriverCookie(cookieStore); for(Cookie cookie : cookieList){ // 整理Cookie,将www去掉,否则回填时将会自动在前面加.,即www.abc.com,将变成.www.abc.com,而无法使用 // 一般情况下在序列化时已经解决了前置www的问题,在这儿应该就不需要再验证了,但考虑到部分已经存在的CookieStore还存在前置www的问题,所以可以应用验证 // cookie = new Cookie(cookie.getName(), cookie.getValue(), // CookieUtils.modifyDomain4Driver(cookie.getDomain()), cookie.getPath(), cookie.getExpiry(), false, false); options.addCookie(cookie); } }

到这儿,可能有人要问了,序列化时干嘛转来转去的,把 Set转换为 CookieStore,纯粹 CookieStore 有其它用处,你也可以不转换直接序列化。

另外,注意在 WebDriver 加载 Cookie 前需要先打开网址,不能直接先加载 Cookie,Cookie 要加载到某个域名下,因此,需要先打开网址,再加载 Cookie,加载完成后 refresh 刷新页面,最后通过规则指定是否加载(登录)成功。

参见:Issue #4861 · SeleniumHQ/selenium

  • Selenium
    17 引用 • 13 回帖
  • 调试
    5 引用 • 35 回帖
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • someone
    作者

    目前还没找到更优雅的方式来解决这个域名问题,不过经测试,有的网站在更改 Cookie 域名后也没问题,有的就不行,显示未登录状态。
    另外,还有一个思路,增加 Driver 池,仅在第一次需要登录,后面直接从池中拿 Driver,但貌似进程一多内存耗不起。
    后面有空了再继续 Google 吧。也欢迎大家讨论。

推荐标签 标签

  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 399 关注
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    198 引用 • 541 回帖
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖
  • Visio
    1 引用 • 2 回帖 • 2 关注
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    76 引用 • 1742 回帖
  • Word
    13 引用 • 40 回帖
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 2 关注
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    7 引用 • 69 回帖 • 1 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖 • 1 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    289 引用 • 4492 回帖 • 655 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    36 引用 • 155 回帖
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    180 引用 • 821 回帖
  • Ruby

    Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。

    7 引用 • 31 回帖 • 253 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • SSL

    SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS 与 SSL 在传输层对网络连接进行加密。

    70 引用 • 193 回帖 • 418 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    76 引用 • 258 回帖 • 632 关注
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    21 引用 • 245 回帖 • 234 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖
  • 浅吟主题

    Jeffrey Chen 制作的思源笔记主题,项目仓库:https://github.com/TCOTC/Whisper

    1 引用 • 28 回帖
  • OpenShift

    红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。

    14 引用 • 20 回帖 • 649 关注
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    132 引用 • 1115 回帖 • 121 关注
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    335 引用 • 324 回帖
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    366 引用 • 1842 回帖 • 2 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖 • 4 关注
  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 647 关注
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    556 引用 • 674 回帖