参考浩劫者12345大佬的脚本
// ==UserScript==// @name Haru君の蹲票// @namespace http://tampermonkey.net/// @version 2.0// @description 参考浩劫者12345大佬的脚本// @author 黎騒君// @match https://*.youzan.com/*// @icon https://img01.yzcdn.cn/v2/image/yz_fc.ico// @grant GM_setValue// @grant GM_getValue// @license MIT// ==/UserScript==(async function () {// 初始化购票信息var ticketToBuy_regextry {ticketToBuy_regex = GM_getValue('autoBuyRegex') ? new RegExp(GM_getValue('autoBuyRegex')) : /电子预售票/;} catch (error) {console.log('正则表达式解析失败,正在使用默认值')ticketToBuy_regex = /电子预售票/;}const idcard = GM_getValue('autoBuyIDCard') ? GM_getValue('autoBuyIDCard') : '';const realname = GM_getValue('autoBuyRealname') ? GM_getValue('autoBuyRealname') : '';const phonenumber = GM_getValue('autoBuyPhonenumber') ? GM_getValue('autoBuyPhonenumber') : '';function checkAutoBuyInfo() {return idcard && idcard.length == 18 && realname && realname.length >= 2 && phonenumber && phonenumber.length == 11}function saveAutoBuyInfo() {console.log('正在保存蹲票配置')GM_setValue('autoBuyRegex', document.getElementById('settingsRegex').value)GM_setValue('autoBuyIDCard', document.getElementById('settingsIDCard').value)GM_setValue('autoBuyRealname', document.getElementById('settingsRealname').value)GM_setValue('autoBuyPhonenumber', document.getElementById('settingsPhonenumber').value)location.reload()}// 设置按钮和设置界面const settingsEl = document.createElement('template')settingsEl.innerHTML = `<button id="settingsBtn" onclick="document.getElementById('settingsOverlay').style.display = 'block'" style="position: fixed;left: 4px;top: 30%;border-radius: 25%;background-color: #0f0;padding: 8px;line-height: 1em;z-index: 999;">蹲票<br>设置</button><div id="settingsOverlay" style="display: none;position: fixed;top: 0;left: 0;right: 0;padding: 8px;border: 2px solid;background-color: white;overflow: auto;z-index: 999;"><p>票名(支持正则表达式匹配):</p><input id="settingsRegex" style="height: initial; background-color: #ff0;" value="${ticketToBuy_regex.source}"><p>举例:<br>所有普票:电子预售票<br>所有32nd普票:电子预售票.*32<br>所有32nd 5月1号普票:5月1日电子预售票.*32<br>所有32nd所有票(包括VIP):32<br>(正则表达式用于匹配商品标题,如果不会请百度)</p><br><br><p>身份证:</p><input id="settingsIDCard" style="height: initial; background-color: #ff0;" value="${idcard}"><br><br><p>姓名:</p><input id="settingsRealname" style="height: initial; background-color: #ff0;" value="${realname}"><br><br><p>手机号:</p><input id="settingsPhonenumber" style="height: initial; background-color: #ff0;" value="${phonenumber}"><br><button id="settingsSetBtn" style="float: right">确定</button></div>`document.body.appendChild(settingsEl.content)document.getElementById('settingsSetBtn').onclick = saveAutoBuyInfo// 所有商品页//if (location.href.includes('/wscshop/feature/goods/all')) {// 蹲票状态覆盖层const overlayEl = document.createElement('template')overlayEl.innerHTML = `<div id="autoBuyStatus" style="position: fixed;left: 8px;bottom: 8px;box-sizing: border-box;max-width: 60%;max-height: 30%;padding: 8px;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;line-height: 1.2;overflow: auto;"></div>`document.body.appendChild(overlayEl.content)// 检查蹲票信息是否正确,不正确则留下提示然后退出if (!checkAutoBuyInfo()) {console.log('购票信息有误')document.getElementById('autoBuyStatus').innerHTML = '请先正确填写蹲票信息!'document.getElementById('autoBuyStatus').style.fontSize = '20px'document.getElementById('autoBuyStatus').style.color = '#ff0'return}// 申请浏览器通知权限Notification.requestPermission().then(() => {new Notification('蹲票脚本已启动', {body: '有票时将通过浏览器通知提醒支付',});})// 启动 worker 以便页面挂起时也能继续蹲票function workerInterval() {setInterval(() => {postMessage('')}, 1000);}const workerBlob = URL.createObjectURL(new Blob([`(${workerInterval.toString()})()`], { type: 'application/javascript' }));const worker = new Worker(workerBlob)let count = 0worker.onmessage = () => {/*https://shop46404892.youzan.com/wscshop/showcase/goods/allGoods.json?pageSize=20&page=1&offlineId=0&openIndependentPrice=0&order=&json=1&uuid=a5f75232-3ec1-66c4-5ec2-b0db133d7765&activityPriceIndependent=1&order_by=algPVD30&goodsType=2&needActivity=0&clientSource=2&tagAlias=&needGroupFilter=false&needGoodsRank=true&supportCombo=true&excludedComboSubType=%5B%22none%22%5D", {*/// 获取前20个商品fetch("/wscshop/showcase/goods/allGoods.json?json=1&order_by=algPVD30", {"method": "GET","credentials": "include"}).then(response => {return response.json();}).then(data => {// 清空蹲票信息显示document.getElementById('autoBuyStatus').innerHTML = `正在蹲以下票(${Notification.permission == "granted" ? '浏览器通知已启用' : '请启用浏览器通知以便接收结果'}):<br>`// 遍历商品data.data.list.forEach((item) => {// 匹配商品标题if (item.title.match(ticketToBuy_regex)) {// 蹲票状态显示在覆盖层document.getElementById('autoBuyStatus').innerHTML += `${item.title} 余票: ${item.totalStock}<br>`if (item.totalStock > 0) {// 有票时发送浏览器通知并跳转商品详情页new Notification('发现有票,请10分钟内前往手动支付', {body: item.title,});document.querySelectorAll('.cap-goods-layout__container>.cap-goods-layout__wrapper>.cap-goods-layout__item').forEach((el) => {if (el.innerText.match(item.title)) {console.log('正在打开商品详情页')el.click()}})}}})count++document.getElementById('autoBuyStatus').innerHTML += `已蹲票次数:${count}<br>`})}}if (!checkAutoBuyInfo()) {console.log('购票信息有误')return}if (location.href.includes('/wscgoods/detail') || location.href.includes('/pay/wscgoods_order')) {await new Promise(r => setTimeout(r, 1000))if (!document.querySelector('.goods-title__main-text').innerText.match(ticketToBuy_regex)) {console.log('商品不匹配,跳过自动点击')return}if (document.querySelector('.mrb__no-goods')) {console.log('没票了!')return}console.log('正在打开购买页面')// 两种“立即购买”按钮,其中一种要点击更内层的 div 才可触发购买界面try {document.querySelector('.goods-btns__button.button--last .goods-btns__authorize .user-authorize__btn-empty').click()} catch (error) {document.querySelector('.goods-btns__button.button--last .goods-btns__authorize').click()}await new Promise(r => setTimeout(r, 500))console.log('正在填写信息')// 填实名信息(需手动触发 input 刷新变量,blur 事件确认购买价),两种页面通用document.querySelectorAll('.sku-messages>.tee-view').forEach((el) => {el.querySelector('.t-cell__value input').focus()if (el.querySelector('.t-cell__title').innerText.includes('身份证')) {el.querySelector('.t-cell__value input').value = idcard}if (el.querySelector('.t-cell__title').innerText.includes('姓名')) {el.querySelector('.t-cell__value input').value = realname}if (el.querySelector('.t-cell__title').innerText.includes('电话') || el.querySelector('.t-cell__title').innerText.includes('手机')) {el.querySelector('.t-cell__value input').value = phonenumber}el.querySelector('.t-cell__value input').dispatchEvent(new Event('input'))el.querySelector('.t-cell__value input').dispatchEvent(new Event('blur'))})setInterval(() => {console.log('正在跳转提交订单界面')// 两种确认购买按钮try {document.querySelector('.pay-btn-order').click()} catch (error) {document.querySelector('.sku-actions__btn--main').click()}}, 500);}// 提交订单页面//if (location.href.includes('/pay/wsctrade_buy')) {await new Promise(r => setTimeout(r, 1000))if (!document.querySelector('.new-goods-list-card__title__text').innerText.match(ticketToBuy_regex)) {console.log('商品不匹配,跳过自动点击')return}console.log('正在提交订单')document.querySelector('.submit-bar__button').click()}})();