【java爬虫】使用selenium通过加载cookie的方式跳过登录

前言

相信很多人在使用selenium的时候都有一个困惑,就是每一次打开的浏览器实例都是不带cookie的,当有一些页面需要登录操作的时候可能就会比较麻烦,每次都需要手动登录。

其实会造成这个问题的原因是每次打开的浏览器都不会加载本地的cookie,相当于环境被隔离了。

这个问题其实也很好解决,解决的办法就是我们首先登陆一次,然后将相应的cookie记录下载,有了cookie信息后,直接加载我们缓存的cookie就可以实现免登陆了。

首先来看一下这个方案的效果,首先是京东免登陆

可以看到当我们打开新的浏览器并且访问京东首页的时候可以很快实现登录,这是因为之前已经缓存了登录的cookie了。

接着我们来看一下百度首页免登陆的效果

因为百度登录后会有一个页面的整体的变化,所以可能看的会比较清楚。

下面我们来介绍一下这个方案的实现细节。

代码简介

整体的思路前面已经介绍过了,实际上就是首先登陆一下,将cookie记录下来,然后下次登录的时候直接加载cookie就可以了。我们记录的方式就是将cookie的信息写到一个txt临时文件中。

Cookie类中我们一共需要关系四个字段,分别是下图中展示的name,value,path和domain

将cookie信息缓存的方法如下

 

    public void save() {
        if (driver == null) {
            return;
        }
        log.info("走到这里了");
        WebDriver.Options manage = driver.manage();
        Set<Cookie> cookies = manage.getCookies();
        // 检查缓存文件是否存在,如果存在则先删除再创建
        if (FileUtil.exist(TMP_COOKIE_PATH)) {
            FileUtil.del(TMP_COOKIE_PATH);
        }
        FileWriter writer = new FileWriter(TMP_COOKIE_PATH);
        for(Cookie c : cookies){
            StringBuilder sb = new StringBuilder();
            sb.append(c.getName() + ";");
            sb.append(c.getValue() + ";");
            sb.append(c.getDomain() + ";");
            sb.append(c.getPath() + ";\n");
            log.info("获取数据=> " + sb.toString());
            writer.append(sb.toString());
        }
    }

其中文件操作我们使用到了hutool工具库,driver是浏览器驱动实例,在执行这个方法前driver应该先被实例化。

将cookie的四个字段的数据变成字符串后写入到文件中即可,给大家展示一下缓存的百度的cookie的文件长什么样

下面说说加载cookie的方法,不知道大家之前有没有注意到,我们调用reload接口的时候,一开始的页面是没有登录的,后面才会变成登录的状态,这是因为cookie中的domian如果单独加载的话是加载不到的,我们需要首先处于当前页面中,再去加载cookie才能成功。加载的方法如下

    public void reload() {
        if (!FileUtil.exist(TMP_COOKIE_PATH)) {
            log.error(TMP_COOKIE_PATH + "文件不存在");
            return;
        }
        System.setProperty("webdriver.chrome.driver", DRIVER_PATH);
        System.setProperty("webdriver.chrome.whitelistedIps", "");
//        EdgeOptions options = new EdgeOptions();
        ChromeOptions options = new ChromeOptions();
        //options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");
        options.addArguments("--remote-allow-origins=*");

        // 启动浏览器
        driver = new ChromeDriver(options);
        // 设置最长等待时间
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        driver.get(URL);
        // 加载cookies
        List<String> lines = FileUtil.readLines(TMP_COOKIE_PATH, CharsetUtil.CHARSET_UTF_8);
        for(int i=0; i<lines.size(); i++) {
            String line = lines.get(i);
            List<String> tmplist = Arrays.asList(line.split(";"));
            Date expire = new Date(new Date().getTime() + 60 * 1000 * 15);
            Cookie cookie = new Cookie(tmplist.get(0), tmplist.get(1), tmplist.get(2), tmplist.get(3), expire);
            log.info("加载cookie=> [name=" + tmplist.get(0) + "] pvalue=" + tmplist.get(1) +
                    "] [domain=" + tmplist.get(2) + "] [path=" + tmplist.get(3) + "]" + " [expire=" + expire.toString() + "]");
            driver.manage().addCookie(cookie);

        }
        driver.manage().window().maximize();
        driver.get(URL);
    }

注意一下,我们调用的Cookie构造函数是下面这个

其中最后一个参数expiry代表的是过期时间,这个我尝试过了,需要设置成一个大于当前时间的值,否则cookie会失效。

最后展示一下完整的代码

@Slf4j
@Service
public class EdgeTestService {

//    private final String DRIVER_PATH = "src/main/resources/msedgedriver.exe";
    private final String DRIVER_PATH = "src/main/resources/chromedriver-120.exe";
    private final String TMP_COOKIE_PATH = "src/main/resources/tmpcookie.txt";
    private final String URL = "https://www.baidu.com/";
//    private final String URL = "https://www.jd.com/?cu=true";
    private WebDriver driver = null;


    public void start() {
        System.setProperty("webdriver.chrome.driver", DRIVER_PATH);
        System.setProperty("webdriver.chrome.whitelistedIps", "");
//        EdgeOptions options = new EdgeOptions();
        ChromeOptions options = new ChromeOptions();
        //options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");
        options.addArguments("--remote-allow-origins=*");

        // 启动浏览器
        driver = new ChromeDriver(options);
        // 设置最长等待时间
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        driver.manage().window().maximize();
        driver.get(URL);
    }

    public void save() {
        if (driver == null) {
            return;
        }
        log.info("走到这里了");
        WebDriver.Options manage = driver.manage();
        Set<Cookie> cookies = manage.getCookies();
        // 检查缓存文件是否存在,如果存在则先删除再创建
        if (FileUtil.exist(TMP_COOKIE_PATH)) {
            FileUtil.del(TMP_COOKIE_PATH);
        }
        FileWriter writer = new FileWriter(TMP_COOKIE_PATH);
        for(Cookie c : cookies){
            StringBuilder sb = new StringBuilder();
            sb.append(c.getName() + ";");
            sb.append(c.getValue() + ";");
            sb.append(c.getDomain() + ";");
            sb.append(c.getPath() + ";\n");
            log.info("获取数据=> " + sb.toString());
            writer.append(sb.toString());
        }
    }

    public void reload() {
        if (!FileUtil.exist(TMP_COOKIE_PATH)) {
            log.error(TMP_COOKIE_PATH + "文件不存在");
            return;
        }
        System.setProperty("webdriver.chrome.driver", DRIVER_PATH);
        System.setProperty("webdriver.chrome.whitelistedIps", "");
//        EdgeOptions options = new EdgeOptions();
        ChromeOptions options = new ChromeOptions();
        //options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");
        options.addArguments("--remote-allow-origins=*");

        // 启动浏览器
        driver = new ChromeDriver(options);
        // 设置最长等待时间
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        driver.get(URL);
        // 加载cookies
        List<String> lines = FileUtil.readLines(TMP_COOKIE_PATH, CharsetUtil.CHARSET_UTF_8);
        for(int i=0; i<lines.size(); i++) {
            String line = lines.get(i);
            List<String> tmplist = Arrays.asList(line.split(";"));
            Date expire = new Date(new Date().getTime() + 60 * 1000 * 15);
            Cookie cookie = new Cookie(tmplist.get(0), tmplist.get(1), tmplist.get(2), tmplist.get(3), expire);
            log.info("加载cookie=> [name=" + tmplist.get(0) + "] pvalue=" + tmplist.get(1) +
                    "] [domain=" + tmplist.get(2) + "] [path=" + tmplist.get(3) + "]" + " [expire=" + expire.toString() + "]");
            driver.manage().addCookie(cookie);

        }
        driver.manage().window().maximize();
        driver.get(URL);
    }

    public void close() {
        if (driver != null) {
            driver.close();
        }
    }

}

 上述的每个方法都对应一个接口

@RestController
public class UserController {

    @Autowired
    private EdgeTestService edgeTestService;

    @RequestMapping("/start")
    @ResponseBody
    public String start() {
        edgeTestService.start();
        return "success";
    }

    @RequestMapping("/close")
    @ResponseBody
    public String close() {
        edgeTestService.close();
        return "success";
    }

    @RequestMapping("/save")
    @ResponseBody
    public String save() {
        edgeTestService.save();
        return "success";
    }

    @RequestMapping("/reload")
    @ResponseBody
    public String reload() {
        edgeTestService.reload();
        return "success";
    }

}

结语

基于上述思路就可以跳过登录环节,我觉得这个方法还是比较好的,如果你有更好的方法欢迎一起讨论交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/232541.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

16.Java程序设计-基于SSM框架的android餐厅在线点单系统App设计与实现

摘要&#xff1a; 本研究旨在设计并实现一款基于SSM框架的Android餐厅在线点单系统&#xff0c;致力于提升餐厅点餐流程的效率和用户体验。通过整合Android移动应用和SSM框架的优势&#xff0c;该系统涵盖了用户管理、菜单浏览与点单、订单管理、支付与结算等多个功能模块&…

时间序列预测 — BiLSTM实现多变量多步光伏预测(Tensorflow)

目录 1 数据处理 1.1 导入库文件 1.2 导入数据集 1.3 缺失值分析 2 构造训练数据 3 模型训练 3.1 BiLSTM网络 3.2 模型训练 4 模型预测 1 数据处理 1.1 导入库文件 import time import datetime import pandas as pd import numpy as np import matplotlib.pyplot…

ChatGPT OpenAI API请求限制 尝试解决

1. OpenAI API请求限制 Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for gpt-3.5-turbo-16k in organization org-U7I2eKpAo6xA7RUa2Nq307ae on reques…

JS基础之原型原型链

JS基础之原型&原型链 原型&原型链构造函数创建对象prototypeprotoconstructor实例与原型原型的原型原型链其他constructorproto继承 原型&原型链 构造函数创建对象 我们先使用构造函数创建一个对象&#xff1a; function Person(){ } var person new Person();…

HarmonyOS创建一个page并实现界面跳转(JavaScript)

上文 HarmonyOS创建JavaScript(类 Web开发模式)项目中 我们接触了这咋类Web开发模式 并创建了一个项目 之前 我们 ArkTS 开发模式的项目 resources目录 下的 base目录下的 profile目录下的 main_pages.json中存放了 我们page目录的配置 但是 我们javaScript模式 下 好像没有哦 …

Docker Volume(存储卷)——7

目录&#xff1a; 什么是存储卷?生活案例为什么需要存储卷?存储卷分类管理卷 Volume 创建卷 方式一&#xff1a; Volume 命令操作方式二&#xff1a; -v 或者--mount 指定方式三&#xff1a; Dockerfile 匿名卷操作案例 Docker 命令创建管理卷Docker -v 创建管理卷Docker mo…

Conda 搭建简单的机器学习 Python 环境

文章目录 Conda 概述Conda 常用命令Conda 自身管理查看 Conda 版本更新 Conda清理索引缓存添加镜像源设置搜索时显示通道地址查看镜像源删除镜像源 环境管理创建虚拟环境删除虚拟环境查看所有虚拟环境复制虚拟环境激活虚拟环境关闭虚拟环境导入、导出环境 包管理虚拟环境下安装…

springboot框架的客制化键盘个性化商城网站

客制化键盘网站是从客制化键盘的各部分统计和分析&#xff0c;在过程中会产生大量的、各种各样的数据。本文以客制化键盘管理为目标&#xff0c;采用B/S模式&#xff0c;以Java为开发语言&#xff0c;Jsp为开发技术、idea Eclipse为开发工具&#xff0c;MySQL为数据管理平台&am…

外网访问内网服务器使用教程

如何在任何地方都能访问自己家里的笔记本上的应用&#xff1f;如何让局域网的服务器可以被任何地方访问到&#xff1f;有很多类似的需求&#xff0c;我们可以统一用一个解决方案&#xff1a;内网穿透。内网穿透的工具及方式有很多&#xff0c;如Ngrok、Ssh、autossh、Natapp、F…

接触huggingface

接触huggingface finetuning llama 按照https://github.com/samlhuillier/code-llama-fine-tune-notebook/tree/main中的教程一步一步了解。 pip install !pip install githttps://github.com/huggingface/transformers.gitmain bitsandbytes # we need latest transforme…

react Hooks(useEffect)实现原理 - 简单理解

useEffect 语法&#xff1a; useEffect(setup, dependencies?) 含义: useEffect 是一个 React Hook&#xff0c;它允许你 将组件与外部系统同步。 useEffect 源码简单理解 一、mountEffect 和 upadateEffect useEffect 与其它 hooks 一样分为 mountEffect 和 upadateEffec…

iOS——定位与地图

平时在写项目的时候可能会遇到需要使用定位服务的地方&#xff0c;比如说获取位置和导航等。因此这里我会使用OC自带的库以及苹果系统的地图来获取定位以及显示在地图上。 开始前的设置 在获取定位前&#xff0c;需要在项目文件的info中添加两个关键字&#xff0c;用于向用户…

SpringBoot AOP切面实现对自定义注解的属性动态修改

文章目录 需求问题解决方案示例代码 需求 项目中共用了一个redis&#xff0c;而项目中部分代码使用了JetCache的Cached注解。所以需要给Cached动态配置area属性值&#xff0c;用来区分dev和test环境。 问题 自定义注解的属性值需要常量值&#xff0c;即static final修饰&…

2013年全国硕士研究生入学统一考试管理类专业学位联考数学试题——解析版

文章目录 2013 级考研管理类联考数学真题一、问题求解&#xff08;本大题共 15 小题&#xff0c;每小题 3 分&#xff0c;共 45 分&#xff09;下列每题给出 5 个选项中&#xff0c;只有一个是符合要求的&#xff0c;请在答题卡上将所选择的字母涂黑。真题&#xff08;2013-01&…

【Amis Low Code 结合FastAPI进行前端框架开发】

官方文档 封装思想 直接复制官网json数据即可开发每个json中的接口由fastapi 转发&#xff08;透传&#xff09;使其开发模式与前端思维一致 基础组件 from amis import Page, Service, App from pydantic import BaseModel, Field from fastapi import FastAPI, Request, …

【计算机网络】TCP|IP协议

目录 前言 什么是TCP/IP协议&#xff1f; TCP/IP协议的层次结构 TCP/IP协议的工作原理 TCP/IP协议的重要性 结语 前言 TCP/IP协议是当今互联网世界中最重要的网络协议之一&#xff0c;它是网络通信的基石&#xff0c;为数据在网络中的传输提供了可靠性和有效性。本文将深…

将RK3399的挖掘机开发板在Android10下设置系统默认为24小时制

将RK3399的挖掘机开发板在Android10下设置系统默认为24小时制 2023/12/9 22:07 应该也可以适用于RK3399的Android12系统 --- a/frameworks/base/packages/SettingsProvider/res/values/defaults.xml b/frameworks/base/packages/SettingsProvider/res/values/defaults.xml -2…

Java王者荣耀火柴人

主要功能 键盘W,A,S,D键&#xff1a;控制玩家上下左右移动。按钮一&#xff1a;控制英雄发射一个矩形攻击红方小兵。按钮控制英雄发射魅惑技能&#xff0c;伤害小兵并让小兵停止移动。技能三&#xff1a;攻击多个敌人并让小兵停止移动。普攻&#xff1a;对小兵造成基础伤害。小…

go自带rpc框架生产环境使用demo

基础使用 序列化使用自带gob协议 server package mainimport ("net""net/rpc" )// 定义一个handler结构体 type HelloService struct { }// 定义handler方法,大小写&#xff0c;参数&#xff0c;返回值都是固定的&#xff0c;否则无法注册 func (receiv…

Axure网页端高交互组件库, 下拉菜单文件上传穿梭框日期城市选择器

作品说明 组件数量&#xff1a;共 11 套 兼容软件&#xff1a;Axure RP 9/10&#xff0c;不支持低版本 应用领域&#xff1a;web端原型设计、桌面端原型设计 作品特色 本作品为「web端组件库」&#xff0c;高保真高交互 (带仿真功能效果)&#xff1b;运用了动态面板、中继…