背景
boss直聘每天打招呼次数是100次。每次都点击太麻烦了(🙃主要是每天精挑细选,勤勤恳恳的投递,回应的就没几个,干脆自动化听天由命吧🥲)。
写个油猴脚本来自动打招呼~
功能:
可填写:薪资、hr是否在线、打招呼数量自动到职位详情页打招呼,自动关闭列表自动翻页微信消息推送
先上效果图😸
需要先搜索职位,到搜索结果页再使用哈
职位搜索列表页:
自动进入详情页:
点击完立即沟通,自动关闭当前页:
操作完后:
微信推送通知:
安装油猴扩展🙈
谷歌商店链接:chromewebstore.google.com/detail/%E7%…
开启扩展:chrome://extensions/
右上角会有猴子图标
新建脚本
脚本源码👻
写完脚本开启后,访问boss直聘网站就会自动执行下面的脚本,出现UI界面了。
// ==UserScript==
// @name boss直聘自动打招呼
// @namespace lz
// @version 1.0
// @description 输入打招呼数量和要求薪资自动打招呼
// @author 迷途小码农
// @match https://www.zhipin.com/*
// @grant none
// ==/UserScript==
// 请先到 https://www.zhipin.com/web/geek/job 页面搜索职位再使用该脚本
// 微信推送:https://www.pushplus.plus/ 扫码登录拿到token替换pushPlusToken即可
(function() {
'use strict';
// 配置项
let state = {
limitMax: 10, // 最大沟通数量 boss限制1天100份
hasUsed: 0, // 已沟通数量
mustOnline: false, // 只沟通在线的,基本很少
minSalary: 0, // k为单位
pushPlusToken: '', // 微信推送,不填则不推送。
waitClickList: [],
hidden:false, // 详情页标题修改和加遮罩层,掩人耳目
}
let endTimeText = null;
let timer = null;
// 收集列表项
async function getList() {
const jobListItems = document.querySelectorAll('.job-list-box .job-card-wrapper');
for (const item of jobListItems) {
const jobName = item.querySelector('.job-name').textContent;
const salary = item.querySelector('.salary').textContent;
//在线标签
const online = item.querySelector('.boss-online-tag');
// 获取详情链接
const aLink = item.querySelector('.job-card-left');
const [min, max] = salary.split('K')[0].split('-').map(x => parseInt(x))
// 必须在线和薪资达标
if (state.mustOnline && !online) {
continue;
}
if (max < state.minSalary) {
continue;
}
state.waitClickList.push(aLink)
}
for (const ele of state.waitClickList) {
// 机会耗尽了
let todayNoCount = localStorage.getItem("todayNoCount")
if(todayNoCount){
finish("【机会耗尽了】")
return
}
// 如果达标了
state.hasUsed = localStorage.getItem("hasUsed") || 0
if (state.hasUsed >= state.limitMax) {
finish()
return
}
// 防止沟通操作频繁
await new Promise((resolve,reject)=>{
ele.click()
setTimeout(()=>{
resolve()
},2000)
})
}
// 一秒后下一页
const urlParams = new URLSearchParams(window.location.search);
const pageParam = urlParams.get('page');
// 最后一页
if(pageParam==10){
finish()
return
}
setTimeout(() => {
nextPage().then(x => {
state.waitClickList = []
getList()
})
}, 1000)
}
// 下一页
async function nextPage() {
return new Promise((resolve, reject) => {
const optionsPages = document.querySelector('.options-pages');
const nextBtn = optionsPages.lastElementChild;
if (nextBtn) {
nextBtn.click()
resolve()
} else {
reject()
}
})
}
// 已完成打招呼
function finish(msg=""){
endTimeText.textContent = `结束时间:${new Date().toLocaleString()}`
setTimeout(()=>{
state.hasUsed = localStorage.getItem("hasUsed")||0
// 发送微信推送消息
state.pushPlusToken && fetch(`https://www.pushplus.plus/send?token=${state.pushPlusToken}&title=boss自动打招呼&content=打招呼数量:${state.hasUsed} 要求hr在线:${state.mustOnline?'是':'否'} ${msg} &template=html`)
clearInterval(timer)
},1000)
return
}
// 绘制ui
function drawUI() {
// 创建一个 <div> 元素作为卡片容器
const cardContainer = document.createElement('div');
cardContainer.style.position = 'fixed';
cardContainer.style.top = '200px';
cardContainer.style.left = '10px';
cardContainer.style.backgroundColor = 'white';
cardContainer.style.padding = '10px';
cardContainer.style.borderRadius = '8px';
cardContainer.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
cardContainer.style.width = '210px';
cardContainer.style.zIndex = '999';
// 创建已打招呼数量展示
const titleText = createDisplay('自动打招呼');
// 创建打招呼数量输入框
const deliveryInput = createInput('打招呼数量', 'number');
// 创建薪资输入框
const salaryInput = createInput('最低薪资K', 'text');
// 创建选择框
const onlineCheckbox = createCheckbox('online', 'HR必须在线');
// 已打招呼数量
const countText = createDisplay('本轮已打招呼数量:');
// 开始时间
const startTimeText = createDisplay('开始时间:');
// 结束时间
endTimeText = createDisplay('结束时间:');
// 创建开始打招呼按钮
const submitButton = createButton('开始打招呼', '#00bebd');
// 创建刷新重置按钮
const resetButton = createButton('刷新重置', '#a2a3a9');
// 添加输入框、展示和按钮到卡片容器中
cardContainer.appendChild(titleText);
cardContainer.appendChild(deliveryInput);
cardContainer.appendChild(salaryInput);
cardContainer.appendChild(onlineCheckbox);
cardContainer.appendChild(countText);
cardContainer.appendChild(startTimeText);
cardContainer.appendChild(endTimeText);
cardContainer.appendChild(submitButton);
cardContainer.appendChild(resetButton);
// 将卡片容器添加到页面中
document.body.appendChild(cardContainer);
let sendCount = 0;
// 点击开始打招呼按钮时的事件处理程序
submitButton.addEventListener('click', () => {
state.limitMax = parseInt(deliveryInput.value);
state.minSalary = parseInt(salaryInput.value);
state.mustOnline = onlineCheckbox.querySelector('input').checked;
startTimeText.textContent = `开始时间:${new Date().toLocaleString()}`
localStorage.removeItem("hasUsed");
localStorage.removeItem("todayNoCount");
getList();
timer = setInterval(()=>{
countText && (countText.textContent = `本轮已打招呼数量:${localStorage.getItem("hasUsed") || 0}` );
},10)
});
// 点击刷新重置按钮时的事件处理程序
resetButton.addEventListener('click', () => {
location.href = location.href.replace(/[\?|&]page=[^&]+/, '');
});
}
// 创建输入框的辅助函数
function createInput(placeholder, type) {
const input = document.createElement('input');
input.type = type;
input.placeholder = placeholder;
input.style.width = '100%';
input.style.padding = '8px';
input.style.marginBottom = '10px';
input.style.border = '1px solid #ccc';
input.style.borderRadius = '4px';
return input;
}
// 创建展示信息的辅助函数
function createDisplay(label) {
const display = document.createElement('div');
display.textContent = label;
display.style.marginBottom = '10px';
return display;
}
// 创建按钮的辅助函数
function createButton(text, backgroundColor) {
const button = document.createElement('button');
button.textContent = text;
button.style.marginTop = '10px';
button.style.width = '100%';
button.style.padding = '8px';
button.style.backgroundColor = backgroundColor;
button.style.color = 'white';
button.style.border = 'none';
button.style.borderRadius = '4px';
button.style.cursor = 'pointer';
return button;
}
// 创建选择框
function createCheckbox(name, label) {
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.name = name;
checkbox.style.marginRight = '5px';
const checkboxLabel = document.createElement('label');
checkboxLabel.textContent = label;
const container = document.createElement('div');
container.appendChild(checkbox);
container.appendChild(checkboxLabel);
return container;
}
// 隐藏页面
function hidden(){
// 删除标题
document.title = "测试";
// 删除图标
var favicon = document.querySelector("link[rel='icon']");
if (favicon) {
favicon.parentNode.removeChild(favicon);
}
// 创建遮挡层
var overlay = document.createElement("div");
overlay.style.position = "fixed";
overlay.style.top = "0";
overlay.style.left = "0";
overlay.style.width = "100%";
overlay.style.height = "100%";
overlay.style.backgroundColor = "white";
overlay.style.zIndex = "9999";
// 将遮挡层添加到文档中
document.body.appendChild(overlay);
}
// 主页
if (location.pathname == '/web/geek/job') {
drawUI();
}
// 详情页
if (location.pathname.includes('/job_detail/')) {
state.hidden && hidden()
let btn = document.querySelector('.btn-startchat');
if (btn && btn.innerText == '立即沟通') {
btn.click();
setTimeout(()=>{
let diologP = document.querySelector('.dialog-con p')
if(!diologP){
let hasUsed = localStorage.getItem("hasUsed") || 0;
localStorage.setItem("hasUsed", ++hasUsed);
}
if(diologP.textContent=='今日沟通人数已达上限,请明天再试')
localStorage.setItem("todayNoCount", true);
},500)
setTimeout(()=>{window.close()},1000)
}
}
})();