给boss直聘的搜索结果加上hr活跃状态,少看点半年活跃的岗位

背景:这段时间找工作,无奈大环境不好,所在城市大部分公司都投了。就是没几个回复的,要么送达,要么已读不回,要么拿了简历没见邀约。然后boss为了争取我们多浏览网站,把一些陈年老醋也拿上台面,让我们误以为有新公司发布职位,结果一点击进去,什么本月活跃,4月内活跃,半年活跃,这些明显就已经不招或者已经招到,只是hr忘了关闭岗位的。还不给过滤条件我们来过滤掉这些岗位,浪费我们时间。

为了过滤一下这些数据,只好自己动手丰衣足食。原理很简单,就是用js代码把没有活跃状态的列表数据用css都给隐藏掉,避免影响我们观感。代码也简单。还有为了不每次都得输入代码,我们要把对应的代码保存到浏览器书签。这样就可以通过点击书签来快速便捷地执行js代码。具体操作就是随意新建一个书签,然后到书签栏找到书签,修改书签。

书签名随你心意,重点是地址栏要把url替换成代码块里面的代码。

javascript: (function() {
    function filterOnlineList() {
        let lis = document.querySelectorAll(".job-card-wrapper");
        for (let i = 0; i < lis.length; i++) {
            let online = lis[i].querySelector('.boss-online-tag');
            if (!online) {
                lis[i].style.display = 'none'
            }
        }
        alertBox('过滤成功');
    }
    function alertBox(msg) {
        var div = document.createElement('div');
        div.style.position = 'fixed';
        div.style.top = '20%';
        div.style.left = '50%';
        div.style.transform = 'translate(-50%, -50%)';
        div.style.backgroundColor = 'rgb(0 190 189)';
        div.style.borderRadius = '5px';
        div.style.color = '#fff';
        div.style.zIndex = 9999;
        div.style.padding = '20px 100px';
        div.style.fontSize = '20px';
        div.style.boxShadow = '0px 0px 10px rgba(0,0,0,.2)';
        div.innerHTML = msg;
        document.body.appendChild(div);
        setTimeout(function() {
            document.body.removeChild(div);
        },
        1000);
    }
    function reBindClick() {
        let pages = document.querySelectorAll('.options-pages a');
        console.log("因为分页每次点击都会重新渲染,所以需要点击后用定时器重新触发绑定点击事件,不然点击后就没有点击事件监听了");
        for (let i = 0; i < pages.length; i++) {
            pages[i].addEventListener('click',
            function() {
                setTimeout(function() {
                    reBindClick();
                    filterOnlineList();
                },
                1000);
            })
        }
    }
    reBindClick();
    filterOnlineList();
})()

不保证后续代码会不会失效,但原理都是相同的,仔细看一下代码就知道如果失效了,该怎么改,本来是想看能不能过滤不仅限于在线状态的,还有一些3日,本周,本月活跃之类的,但仔细看过接口后发现查询列表接口没返回这个状态,只有一个online的布尔值。其它的数据是后端渲染html页面生成的数据,不是通过接口返回的数据,所以就没办法,只能退而求之。  

注意:如果你们需要修改代码,要注意以下几点,代码结束分号要有,不然可能会报错。好像也无法使用window,可能是chrome的安全考虑。前面的javascript:是必须的,不然点击书签的时候,浏览器不会执行代码,这里加了个提示框来提示代码是否有成功执行,不用提示框也是可以的,只是可能不知道有没有执行成功

进阶版

后面又想了下,折腾了有一天多吧,算是折腾出一个更好一点的版本

思路都注释在代码里面了。用的fetch去获取对应的html页面,再从html页面里面拿出对应的数据,原理简单,但中间经历的坑也是不少的。

坑一,也是最主要的坑:boss的html页面如果获取速度慢了,会给个302的临时重定向返回回来,你们看到的效果就是点击查询列表页面的任意一个打开的页面会显示一个loading的效果,实际这个loading就是重定向的一个页面,后面它响应到资源了才会再重定向回来目标页面,用户无感,但是对于我们这种只是想拿点数据的就是灾难了,因为它一重定向,浏览器就自动重定向,我们就拿不到数据。最后只能是fetch可以拿到数据的就fetch,fetch拿不到数据了就用iframe加载实际页面,拿到数据后,再删除iframe.

坑二:不能短时间内频繁触发请求,不然所有请求都给你弄成302,所以我只好牺牲速度,保证效果,用Promise await慢慢获取数据,避免触发boss的302 策略。

坑三:用iframe也有坑,本来想用DOMContentLoaded来加快循环速度的,就是拿到html就可以了,因为所需数据就在html页面,不需要css js 图片那些乱七八糟的东西,计划拿完就删掉它,浏览器自然就取消请求了。结果实验了却监听不了这个,最后还是老老实实用回onload,可是用回onload也还是有坑,用iframe加载页面,某些页面也会触发302,这时候你立马去拿值,是拿不到值的,因为真正的页面还没回来,所以只好又用定时器再延时获取一下数据,但这个时间实在不好把控,还有每次拿完要删了iframe,不然你后面再用这个iframe,不会触发onload。

坑四:有些hr是没有状态的,例如一些猎头还有一些奇怪的hr,是空值来的

贴一下效果图,样式随便弄了一下

压缩书签版本,复制到书签去的版本

javascript:(function(){function initBossHrStatus(){let isPageChange=false;function alertBox(msg){var div=document.createElement('div');div.style.cssText='position: fixed; top: 20%; left: 50%; transform: translate(-50%, -50%); background-color: rgb(0 190 189); border-radius: 5px; color: #fff; z-index: 9999; padding: 20px 100px; font-size: 20px; box-shadow: 0px 0px 10px rgba(0,0,0,.2);';div.innerHTML=msg;document.body.appendChild(div);setTimeout(function(){document.body.removeChild(div)},2000)}function reBindClick(){let pages=document.querySelectorAll('.options-pages a');for(let i=0;i<pages.length;i++){pages[i].addEventListener('click',function(){isPageChange=true;setTimeout(function(){new initBossHrStatus()},1000)})}}async function getListStatus(){alertBox('开始更新状态....,网站安全策略问题,更新会比较缓慢。');let links=Array.from(document.querySelectorAll('.job-list-box .job-card-left')).filter((node)=>{let online=node.querySelector('.boss-online-tag');if(online){setText(node,'在线')}return!online});function setText(node,statusTxt){let pNode=document.createElement('p');pNode.innerHTML=statusTxt;console.log(statusTxt);pNode.style.cssText="display:flex;padding:5px;background:#e1f5e3;color:green;";node.querySelector('.job-info').after(pNode)}for(let i=0;i<links.length;i++){if(isPageChange){break}await new Promise((resolve)=>{setTimeout(()=>{resolve()},2000)});let node=links[i];let link=node.href;let statusTxt=await getHtml(link);console.log(statusTxt);if(statusTxt===''){statusTxt='未知状态'}setText(node,statusTxt);if(i===links.length){alertBox('更新完成')}}}function getHtml(link){function fetchHtml(){return fetch(link,{redirect:'error'}).then((res)=>{return res.text()}).then(async(data)=>{const divNode=document.createElement("div");divNode.insertAdjacentHTML('afterbegin',data);const node=divNode.querySelector('.boss-active-time');return node?node.textContent:'猎头,或者没状态的hr'}).catch(async(error)=>{return await getStatusByIframe(link)})}return fetchHtml()}async function getStatusByIframe(link){let iframe=document.createElement('iframe');iframe.src=link;iframe.id='tempIframe';iframe.style.cssText="width:0;height:0;";document.body.appendChild(iframe);return await new Promise((resolve)=>{let iframe=document.querySelector('#tempIframe');iframe.onload=function(){let node=iframe.contentWindow.document.querySelector('.boss-active-time');function returnVal(){let status=node?node.textContent:'可能不存在状态,也可能没获取到真实数据,大概率后者';resolve(status);setTimeout(()=>{document.body.removeChild(iframe)},500)}if(node){returnVal()}else{setTimeout(()=>{node=iframe.contentWindow.document.querySelector('.boss-active-time');returnVal()},2000)}}})}reBindClick();getListStatus();return true}new initBossHrStatus()})()

 源码版,给你们看代码的

javascript: (function() {
    function initBossHrStatus(){
        let isPageChange = false;

        function alertBox(msg) {
            var div = document.createElement('div');
            div.style.cssText = 'position: fixed; top: 20%; left: 50%; transform: translate(-50%, -50%); background-color: rgb(0 190 189); border-radius: 5px; color: #fff; z-index: 9999; padding: 20px 100px; font-size: 20px; box-shadow: 0px 0px 10px rgba(0,0,0,.2);';
            div.innerHTML = msg;
            document.body.appendChild(div);
            setTimeout(function() {
                document.body.removeChild(div);
            },
            2000);
        }
        function reBindClick() {
            let pages = document.querySelectorAll('.options-pages a');
            /*因为分页每次点击都会重新渲染,所以需要点击后用定时器重新运行方法"*/
            for (let i = 0; i < pages.length; i++) {
                pages[i].addEventListener('click',
                function() {
                    isPageChange = true;
                    setTimeout(function() {
                        new initBossHrStatus();
                    },
                    1000);
                })
            }
        }
        async function getListStatus(){
            alertBox('开始更新状态....,网站安全策略问题,更新会比较缓慢。');
            let links = Array.from(document.querySelectorAll('.job-list-box .job-card-left')).filter((node)=>{
                let online = node.querySelector('.boss-online-tag');
                if(online){
                    setText(node,'在线');
                }
                return !online;
            });
    
            function setText(node,statusTxt){
                let pNode = document.createElement('p');
                pNode.innerHTML = statusTxt;
                console.log(statusTxt);
                pNode.style.cssText = "display:flex;padding:5px;background:#e1f5e3;color:green;";
                node.querySelector('.job-info').after(pNode);
            }
            /*要把在线的过滤掉,一来减少请求,二来请求的数据也不存在下面代码的class .boss-active-time,会报错'*/
            for (let i = 0; i < links.length; i++) {
                if(isPageChange){
                    /*切换了分页, 要中断循环*/
                    break;
                }
                await new Promise((resolve) => {
                    setTimeout(()=>{
                        /*做个延时处理,好像boss有做ddos处理,频繁请求会触发302重定向,最终导致拿不到html页面数据*/
                        resolve();
                    }, 2000);
                });
                let node = links[i];
                let link = node.href;
                let statusTxt = await getHtml(link);
                console.log(statusTxt);
                if(statusTxt===''){
                    statusTxt = '未知状态';
                }
                setText(node,statusTxt);
                if(i===links.length){
                    alertBox('更新完成');
                }
            }
            
            
        }
        
        function getHtml(link){
            function fetchHtml(){
                /*设置不允许重定向,让其报错,报错后通过iframe来获取数据,虽然慢点,但起码可以获取到数据*/
                return fetch(link, { redirect: 'error' }) 
                .then((res)=>{    
                    return res.text();
                }).then(async(data)=>{    
                    const divNode = document.createElement("div");
                    divNode.insertAdjacentHTML('afterbegin', data);
                    const node = divNode.querySelector('.boss-active-time');
                    return node?node.textContent:'猎头,或者没状态的hr';
                }).catch(async(error)=>{
                    /*请求被302临时重定向了,无法获取到数据,需要用iframe来获取了*/
                    return await getStatusByIframe(link);
                })
            }
            return fetchHtml();
        }
        
        
        async function getStatusByIframe(link){
            let iframe = document.createElement('iframe');
            iframe.src = link;
            iframe.id = 'tempIframe';
            iframe.style.cssText = "width:0;height:0;";
            document.body.appendChild(iframe);
           
            return await new Promise((resolve)=>{
                let iframe = document.querySelector('#tempIframe');
                iframe.onload = function(){
                    let node = iframe.contentWindow.document.querySelector('.boss-active-time');
    
                    function returnVal(){
                        let status = node?node.textContent:'可能不存在状态,也可能没获取到真实数据,大概率后者';
                        resolve(status);
                        setTimeout(()=>{
                            document.body.removeChild(iframe);
                        },500)
                    }
    
                    if(node){
                        returnVal();
                    }else{
                        /*应该是iframe页面也触发了302临时重定向,导致这时候获取,不能拿到真正的数据,所以延迟试试,但这个延时不好控制,调小了,获取不到数据,调大了,显得反应很慢(不过慢其实没啥影响,因为你不可能一下子浏览全部列表数据,一条一条来,应该是可以的)*/
                        setTimeout(()=>{
                            node = iframe.contentWindow.document.querySelector('.boss-active-time');
                            returnVal();
                        },2000)
                    }
                }
                
            })          
        }
        reBindClick();
        getListStatus();
        return true;
    }
    /*虽然反应速度可能不是很理想,但只是个小功能,所以有效果就行,不想继续优化了*/
    new initBossHrStatus();
})()

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

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

相关文章

阿里巴巴春招的后端面经来啦~

操作系统 一个操作系统&#xff0c;我们在衡量它的内存占用的时候&#xff0c;它一般会有哪些内存的部分&#xff1f; 读者答&#xff1a;堆和栈 补充&#xff1a; 这个其实是问你对free命令的理解。 主机的内存做一些清理的动作。你知道这里面会涉及到对哪些内存区域进行操…

yolov5-v7.0实例分割快速体验

简介 &#x1f680;yolov5-v7.0版本正式发布&#xff0c;本次更新的v7.0则是全面的大版本升级&#xff0c;最主要的功能就是全面集成支持了实例分割&#xff0c;yolov5已经集成检测、分类、分割任务。 前面几篇文章已经介绍过关于Yolov5的一些方面 yolov5目标检测:https://bl…

CIE (PCI Express) 1x, 4x, 8x, 16x总线端子说明

1、概述 PCI Express作为一种高带宽、低引脚数、串行、互连技术。它是为了取代旧的PCI和AGBus标准而设计的。PCIe比旧标准有许多改进&#xff0c;包括更高的最大系统总线吞吐量、更低的I/O引脚数和更小的物理占地面积、更好的总线设备性能扩展、更详细的错误检测和报告机制&am…

4.7--计算机网络之TCP篇之socket编程--(复习+深入)---好好沉淀,加油呀

1.针对 TCP 应该如何 Socket 编程&#xff1f; 1.服务端和客户端初始化 socket&#xff0c;得到文件描述符&#xff1b; 2.服务端调用 bind&#xff0c;将 socket 绑定在指定的 IP 地址和端口; 3.服务端调用 listen&#xff0c;进行监听&#xff1b; 4.服务端调用 accept&#…

版本控制工具Git的常见命令与使用方法

目录概述基础命令提交代码把代码提交到暂存区把代码提交到版本库同一笔提交想追加修改回退代码对代码进行了修改&#xff0c;想回退工作区的修改执行了add操作&#xff0c;想回退到工作区执行了commit操作&#xff0c;想撤销修改执行了commit操作&#xff0c;想回退到暂存区挑代…

二、Java 并发编程(1)

本章概要 常见的 Java 线程创建方式 继承 Thread 类实现 Runnable 接口通过 ExecutorService 和 Callable 接口实现有返回值的线程基于线程池 Java 线程池的原理 线程复用线程池的核心组件和核心类Java 线程池的工作流程线程池的拒绝策略 相对于传统的单线程&#xff0c;多线…

Nuxt项目动态路由带参接参

我们创建一个Nuxt项目 然后 在pages目录下创建 engineering.vue文件 参考代码如下 <template><div><div>工程界面</div><nuxt-child></nuxt-child></div> </template><script> export default {name: EngineeringPage …

java微服务商城高并发秒杀项目--008.订单服务继承Sentinel以及sentinel安装dashboard

在shop-order-service增加Sentinel依赖&#xff1a;<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-a libaba-sentinel</artifactId> </dependency>安装dashboard组件windows系统直接在1.8.0.jar中cm…

SMPL Model转换为bvh格式 (SMPL to BVH ) Python

BVH BVH是BioVision等设备对人体运动进行捕获后产生文件格式的文件扩展名。 BVH文件 BVH文件包含角色的骨骼和肢体关节旋转数据。BVH 是一种通用的人体特征动画文件格式&#xff0c;广泛地被当今流行的各种动画制作软件支持。通常可从记录人类行为运动的运动捕获硬件获得。 B…

说说如何借助webpack来优化前端性能?

通过webpack优化前端的手段有&#xff1a; ① JS代码压缩 ② CSS代码压缩 ③ HTML文件代码压缩 ④ 文件大小压缩 ⑤ 图片压缩 ⑥ Tree Shaking ⑦ 代码分离 ⑧ 内联 chunk 1、JS代码压缩 terser是一个JavaScript的解释、绞肉机、压…

2023年第十四届蓝桥杯将至,来看看第十三届蓝桥杯javaB组题目如何

ฅ(๑˙o˙๑)ฅ 大家好, 欢迎大家光临我的博客&#xff1a;面向阿尼亚学习 算法学习笔记系列持续更新中~ 文章目录一、前言二、2022年蓝桥杯javaB组省赛真题目录A:星期计算[5分]思路⭐代码&#x1f31f;B 山(5分)思路⭐代码&#x1f31f;C 字符统计(10分)思路⭐代码&#x1f3…

【学习笔记】启示录 - 打造用户喜爱的产品(阅读摘录)

【学习笔记】启示录 - 打造用户喜爱的产品&#xff08;阅读摘录&#xff09; 图书信息 Marty Cagan 著 七印部落 译 人员&#xff1a; 负责定义和开发产品的团队成员的角色和职责 流程&#xff1a; 探索、开发富有创意的产品时&#xff0c;反复应用的步骤和成功的实践经验 产品…

python 实现二叉搜索树的方法有哪些?

树的介绍 树不同于链表或哈希表&#xff0c;是一种非线性数据结构&#xff0c;树分为二叉树、二叉搜索树、B树、B树、红黑树等等。 树是一种数据结构&#xff0c;它是由n个有限节点组成的一个具有层次关系的集合。用图片来表示的话&#xff0c;可以看到它很像一棵倒挂着的树。…

Unity中将项目通用的公共模块封装成类库dll

前言&#xff1a; 最近公司的App项目开始用Unity来开发了&#xff0c;可能大家好奇为什么不用原生的AndroidStudio来开发&#xff0c;主要原因是因为我们做的都是医疗类的App&#xff0c;里面或多或少都用到了Unity虚拟场景&#xff0c;以前我们都是采用Android集成Unity来满足…

如何让chatGPT变成中文-ChatGPT怎么完整输出

ChatGPT厉害在哪 ChatGPT 厉害在于它是使用深度学习技术进行训练的大型神经网络模型&#xff0c;可以从大量的自然语言数据中自动学习语言模式、词汇和语法规则&#xff0c;从而生成相对流畅和准确的文本。以下是 ChatGPT 的主要优势&#xff1a; 可以根据输入自动进行语言生成…

Spark 之 解析json的复杂和嵌套数据结构

本文主要使用以下几种方法&#xff1a; 1&#xff0c;get_json_object()&#xff1a;从一个json 字符串中根据指定的json 路径抽取一个json 对象 2&#xff0c;from_json()&#xff1a;从一个json 字符串中按照指定的schema格式抽取出来作为DataFrame的列 3&#xff0c;to_j…

身临其境数字世界:探索VR全景元宇宙展厅

随着科技的不断发展&#xff0c;虚拟现实技术已经成为我们生活中的一部分。VR全景元宇宙展厅作为其中的一种形式&#xff0c;正越来越受欢迎。在这里&#xff0c;您可以探索未知的世界&#xff0c;体验全新的视觉和感官体验。 一、VR全景元宇宙展厅的概述 VR全景元宇宙展厅是一…

前端学习:HTML链接

目录 一、HTML超链接&#xff08;链接&#xff09; 二、HTML链接语法 三、target属性 target属性值展示 四、name属性 五、补充 关于创建电子邮件链接时如何发送邮件内容 在进行抄送时&#xff0c;需要使用关键字&#xff1a;cc 在进行密送时&#xff0c;需要使用关键字&a…

Linux小黑板(14):基于环形队列的生成消费者模型

"多少人都&#xff0c;生来纯洁完美&#xff0c;心底从不染漆黑。" 我们先来瞅瞅我们之前基于阻塞队列的生产消费者模型代码。 void Push(const T& in){// 生产任务pthread_mutex_lock(&_mutex);while(is_full()){pthread_cond_wait(&_pcond,&_mute…

4款【新概念APP】对比+免费下载

4款【新概念APP】对比免费下载4款【新概念APP】对比免费下载新概念英语咖&#xff08;体积小、无广告、全免费、不能倍速播放&#xff09;新概念英语全册&#xff08;免费&#xff0c;但强制广告&#xff0c;否则不能播放音频。可以倍速&#xff09;新概念英语全四册&#xff0…
最新文章