在您安装前,Greasy Fork 希望您知道此脚本包含可能不受欢迎的功能,也许会帮助脚本作者获利,而不能给你带来任何收益。
作者从这份脚本获得佣金,例如透过改写链接或提供优惠券代码以包含推荐或附属代码。
脚本作者的说明:
【此提示为GreasyFork代码规范要求含有查券功能的脚本必须添加,请知悉!】
网购优惠查询小助手功能:1,淘宝、天猫商品详情页自动显示优惠券信息,包括隐藏优惠券的信息,点击领券按钮可快速领取优惠券。2.淘宝、天猫、京东搜索商品列表,每个商品自动显示优惠券面额,为你提供快速对比的效果!
// ==UserScript== // @name 网购优惠查询小助手,淘宝、天猫、京东隐藏优惠券自动查询,搜索结果优惠券信息直接展示,无需进入详情页,快速对比同款优惠信息,持续维护中 // @name:zh 网购优惠查询小助手,淘宝、天猫、京东隐藏优惠券自动查询,搜索结果优惠券信息直接展示,无需进入详情页,快速对比同款优惠信息,持续维护中 // @name:zh-TW 網購優惠查詢小助手,淘寶、天貓、京东隱藏優惠券自動查詢,搜索結果優惠券信息直接展示,無需進入詳情頁,快速對比同款優惠信息,持續維護中 // @description 网购优惠查询小助手功能:1,淘宝、天猫商品详情页自动显示优惠券信息,包括隐藏优惠券的信息,点击领券按钮可快速领取优惠券。2.淘宝、天猫、京东搜索商品列表,每个商品自动显示优惠券面额,为你提供快速对比的效果! // @description:zh 网购优惠查询小助手功能:1,淘宝、天猫商品详情页自动显示优惠券信息,包括隐藏优惠券的信息,点击领券按钮可快速领取优惠券。2.淘宝、天猫、京东搜索商品列表,每个商品自动显示优惠券面额,为你提供快速对比的效果! // @description:zh-TW 網購優惠查詢小助手功能:1,淘寶、天貓商品詳情頁自動顯示優惠券信息,包括隱藏優惠券的信息,點擊領券按鈕可快速領取優惠券。2.淘寶、天貓、京東搜索商品列表,每個商品自動顯示優惠券面額,爲你提供快速對比的效果! // @namespace coupon // @version 1.78 // @author zhihu // @license End-User License Agreement // @match *://*.taobao.com/* // @match *://*.tmall.com/* // @match *://chaoshi.detail.tmall.com/* // @match *://*.tmall.hk/* // @match *://*.liangxinyao.com/* // @match *://*.jd.com/* // @match *://*.jd.hk/* // @match *://*.yiyaojd.com/* // @match *://*.vip.com/* // @match *://*.vipglobal.hk/* // @exclude *://login.taobao.com/* // @exclude *://login.tmall.com/* // @exclude *://uland.taobao.com/* // @exclude *://pages.tmall.com/* // @exclude *://wq.jd.com/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant GM_xmlhttpRequest // @grant GM.xmlHttpRequest // @grant GM_getValue // @grant GM.getValue // @grant GM_setValue // @grant GM.setValue // @antifeature referral-link 【此提示为GreasyFork代码规范要求含有查券功能的脚本必须添加,请知悉!】 // @connect api.zhihupe.com // @grant unsafeWindow // ==/UserScript== (function() { 'use strict'; //全局对象 const window = unsafeWindow||window; const API_DOMAIN = 'https://api.zhihupe.com'; //const API_DOMAIN = 'http://127.0.0.1:7001'; //---------------------------公共方法开始--------------------------- const Utils = { //兼容 Tampermonkey | Violentmonkey | Greasymonkey 4.0+ getValue:function(name, value) { if (typeof GM_getValue === "function") { return GM_getValue(name, value); } else { return GM.getValue(name, value); } }, //兼容 Tampermonkey | Violentmonkey | Greasymonkey 4.0+ setValue:function(name, value) { if (typeof GM_setValue === "function") { GM_setValue(name, value); } else { GM.setValue(name, value); } }, /** * 添加css * @params {String||Array} css - css样式 */ appendStyle(css){ let style = document.createElement('style'); if(css instanceof Array){ style.textContent = css.join(''); }else{ style.textContent = css } style.type = 'text/css'; let doc = document.head || document.documentElement; doc.appendChild(style); }, /** * 添加js文件 * @params {String} url - js文件地址 */ appendScript:function(type,content) { let script = document.createElement('script'); if(type === 'url'){ script.src = content; }else{ script.innerHTML = content; } var docu = document.body; docu.appendChild(script); }, getObjectValue(object,path,defValue){ let obj = object; if(typeof path === 'string'){ const reg = /[^\[\].]+/g; path = path.match(reg); } for(const key of path){ if(!obj) { return defValue } obj = obj[key]; } return obj === undefined ? defValue : obj; }, getQueryParam(query,url = ''){ let search = '' if(url&&url.indexOf('?' !== -1)){ search = url.split('?').slice(1).join(); }else{ search = window.location.search.replace('?','') } const queryArr = search.split('&'); let param = null; queryArr.forEach(item => { const paramArr = item.split('='); if(paramArr[0] === query){ param = paramArr[1]; } }); return param; }, getUrlid(url) { var id =""; if (url.indexOf("?") != -1) { url = url.split("?")[0] } if (url.indexOf("#") != -1) { url = url.split("#")[0] } var text = url.split("/"); id = text[text.length - 1]; id = id.replace(".html", ""); return id }, monitorElement(attr){ let attrArr = []; if(attr instanceof Array&&attr.length > 0){ attrArr = [...attr]; }else{ attrArr.push(attr) } let element = null; return new Promise((resolve, reject) => { attrArr.forEach(ele =>{ let timer = null,count = 0; element = document.querySelector(ele); timer = setInterval(()=>{ if(element){ clearInterval(timer); resolve(element); } if(count > 50){ clearInterval(timer); reject('未找到元素节点'); } element = document.querySelector(ele); count ++ },200) }) }) } } const initData = { wenku:{ codeInputElement:"#code", loginCode:"123456", }, coupon:{ shopGuideGroupText:'捡漏导购Q群', shopGuideGroup:'188872170', hasCouponBtnText:'领券购买', noCouponBtnText:'直接购买', noCommissionBtnText:'搜索同款优惠', buyUrl:'http://tool.wezhicms.com/coupon/getscan.php', tbShortUrlApi:'https://api.shop.xuelg.com/?id={ID}&m=shangpin', tbShortUrlApiReqQuery: 'shorturl', blackElement:['.coupon-wrap','#toolbar-qrcode'], taobao:{ detailCouponMountElement:['.SecurityPrice--securityPrice--25lJx-X','.Price--root--1CrVGjc'], searchGoodsCardElement:['.Content--content--sgSCZ12 .Card--doubleCardWrapper--L2XFE73','.Content--content--sgSCZ12 .Card--doubleCardWrapperMall--uPmo5Bz','.J_TItems .item .photo a'] }, tmall:{ detailCouponMountElement:['.SecurityPrice--securityPrice--25lJx-X','.Price--root--1CrVGjc'] }, tmallcs:{ searchGoodsCardElement:['.feeds-list .feeds-item a'] }, jd:{ detailCouponMountElement:'#J-summary-top', searchGoodsCardElement:['.J-goods-list .gl-i-wrap .p-img a','.jSearchListArea .jItem .jPic a'] } } } class Coupon{ //优惠券查询地址 couponApiUrl = ''; //优惠券展示节点 initElement = null; get isHasCoupon(){ return this.couponInfo?.couponAmount > 0; } constructor(platform){ this.platform = platform; //优惠券信息 let couponInfo = {}; Object.defineProperty(this,'couponInfo',{ set(value){ couponInfo = value; //更新优惠券信息 this.updateCouponHtml(); }, get(){ return couponInfo; } }) } /* 获取优惠券信息 return {Promise} */ getCouponInfo(){ if(!this.goodsId) throw new TypeError('商品ID获取失败'); if(!this.couponApiUrl) throw new TypeError('优惠券查询链接不存在'); return new Promise((resolve, reject) => { fetch(this.couponApiUrl,{ method:'GET', mode:'cors', }).then(r=>r.json()).then(response=>{ if(response.code === 1){ resolve(response.data) }else{ reject(new TypeError(response.message)) } }).catch(err=>{ reject(err) }) }); } getTbShortUrl(id){ const api = initData.coupon.tbShortUrlApi.replace('{ID}',id) return new Promise((resolve, reject) => { fetch(api,{ method:'GET', mode:'cors', }).then(r=>r.json()).then(response=>{ resolve(Utils.getObjectValue(response,initData.coupon.tbShortUrlApiReqQuery)); }).catch(err=>{ reject(err) }) }); } /* *插入优惠券节点 * params {ElementObject} 定位元素对象 * params {String} position 插入位置 */ async appendCouponElement(element,position = "afterend"){ //插入css this.css&&Utils.appendStyle(this.css) //插入Html this.initElement = this.loadingElement||null; if(this.initElement)element.insertAdjacentElement(position,this.initElement); } async updateCouponHtml(){ if(this.initElement){ this.initElement.innerHTML = this.couponHtml //添加关闭二维码事件 const qr = document.querySelectorAll('.closeQr'); if(qr.length > 0){ console.log(qr) Array.from(qr).forEach(e=>{e.onclick = ()=> e.parentNode.style.display = 'none'}) } } } async updateCouponErrorHtml(){ if(this.initElement)this.initElement.innerHTML = this.couponHtml } } class DetailCoupon extends Coupon{ css = ` .zhihu-coupon:hover .zhihu-scan{ display:block!important; } ` get mobileAppText(){ let text = '手机淘宝'; switch (this.platform) { case 'tmall': case 'taobao': text = '手机淘宝' break; case 'jd': text = '手机京东或微信' break; } return text; } get couponHtml(){ let couponHtml = '<text style="font-size: 20px;">暂未发现优惠券</text>', tipsText = initData.coupon.shopGuideGroupText + ':' + initData.coupon.shopGuideGroup, btnText = initData.coupon.noCouponBtnText, buyLink = `${initData.coupon.buyUrl}?link=${this.couponInfo.shortUrl}&platform=${encodeURIComponent(this.mobileAppText)}`, qrcodebox = `<div style="position:fixed;bottom:50px;right:50px;width: 124px; z-index: 999999;">${this.qrcodeHtml}</div>` if(this.isHasCoupon){ couponHtml = ` <text style="font-size: 20px;">优惠券:</text> <text style="font-size: 18px; margin-right: 2px;">¥</text>${Math.round(this.couponInfo.couponAmount)} `; tipsText = `${this.couponInfo.couponStartTime} - ${this.couponInfo.couponEndTime}`; btnText = initData.coupon.hasCouponBtnText; }else if(this.noCommission){ couponHtml = '<text style="font-size: 20px;">暂未发现优惠券</text>'; buyLink = ''; btnText = initData.coupon.noCommissionBtnText; qrcodebox = ''; } return ` <div style="width: 279px; color: rgb(255, 255, 255); padding-left: 20px; box-sizing: border-box;"> <div style="font-size: 28px; line-height: 28px; font-weight: 900; white-space: nowrap;"> ${couponHtml} </div> <div style="margin-top: 5px;">${tipsText}</div> </div> <div style="text-align: center; width: calc(100% - 279px); font-size: 20px; color: rgb(255, 255, 255); font-weight: bold; letter-spacing: 1px; cursor: pointer;"> <a target="_blank" href="${buyLink}" style="text-decoration: none; color: rgb(255, 255, 255);">${btnText}</a> </div> <div class="zhihu-scan" style="position: absolute; display: block; right: 426px; padding-right: 5px; top: -10px; width: 124px; z-index: 999999;"> ${this.qrcodeHtml} </div> ${qrcodebox} ` } get loadingElement(){ const div = document.createElement('div'); div.classList = 'zhihu-coupon'; div.style = 'background-image: url(https://gw.alicdn.com/tfs/TB16d.1ykPoK1RjSZKbXXX1IXXa-665-115.png); position: relative; font-family: HelveticaNeue-Bold, "Helvetica Neue"; width: 426px; height: 75px; background-size: 100%, 100%; background-repeat: no-repeat; margin: 10px 0px 10px 10px; display: flex; align-items: center;' div.innerHTML = ` <div style="width: 279px; color: rgb(255, 255, 255); padding-left: 20px; box-sizing: border-box;"> <div style="font-size: 28px; line-height: 28px; font-weight: 900; white-space: nowrap;"> <text style="font-size: 20px;">正在搜索优惠券···</text> </div> </div> `; return div; } get qrcodeHtml(){ if(!this.couponInfo?.shortUrl) return ''; return ` <i class="closeQr" style="position: absolute;right: -2px;top: -2px;cursor: pointer;"><svg t="1712718308343" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1614" width="18" height="18"><path d="M512 960C264.97 960 64 759.03 64 512S264.97 64 512 64c247.04 0 448 200.97 448 448S759.04 960 512 960z m0-861.54C283.98 98.46 98.46 283.98 98.46 512S283.98 925.54 512 925.54 925.54 740.02 925.54 512 740.02 98.46 512 98.46z" fill="#666666" p-id="1615"></path><path d="M353.61 687.62c-4.41 0-8.82-1.68-12.18-5.05-6.73-6.73-6.73-17.63 0-24.37l316.78-316.78c6.73-6.73 17.63-6.73 24.37 0s6.73 17.63 0 24.37L365.79 682.57a17.14 17.14 0 0 1-12.18 5.05z" fill="#666666" p-id="1616"></path><path d="M670.39 687.62c-4.41 0-8.82-1.68-12.18-5.05L341.43 365.79c-6.73-6.73-6.73-17.63 0-24.37s17.63-6.73 24.37 0L682.58 658.2c6.73 6.73 6.73 17.63 0 24.37a17.18 17.18 0 0 1-12.19 5.05z" fill="#666666" p-id="1617"></path></svg></i> <div style="text-align: center; padding: 12px 5px 8px; background: rgb(255, 255, 255); border: 1px solid rgba(0, 0, 0, 0.08); border-radius: 12px;"> <div style="margin: 0px auto; width: 100px;"> <img src="http://v.zhihupe.com/enQrcode?url=${this.couponInfo.shortUrl}" style="width: 100px;"> </div> <div style="margin-top: 4px;">${this.mobileAppText}扫一扫,享优惠</div> </div> ` } constructor(platform){ super(platform); this.addCouponElement(); } async addCouponElement(){ try { //获取商品ID和优惠券API链接 if(this.platform == 'taobao'||this.platform == 'tmall'){ this.goodsId = Utils.getQueryParam('id')||null; const shortUrl = await this.getTbShortUrl(this.goodsId); console.log(shortUrl) this.couponApiUrl = API_DOMAIN + '/api/coupon/info?platform=taobao' + '&id=' + shortUrl }else if(this.platform === 'jd'){ this.goodsId = Utils.getUrlid(window.location.href)||null; this.couponApiUrl = API_DOMAIN + '/api/coupon/info?platform=jd' + '&id=' + this.goodsId; } //添加优惠券元素 const attr = initData.coupon[this.platform]['detailCouponMountElement']; console.log(initData.coupon[this.platform]) const element = await Utils.monitorElement(attr); this.appendCouponElement(element); //获取商品优惠券 this.couponInfo = await this.getCouponInfo(); } catch (error) { //添加无佣金状态 this.noCommission = true; //更新无佣金html this.updateCouponErrorHtml() console.log(error) } } } class SearchCoupon extends Coupon{ get couponHtml(){ let html = `<span style="background: rgb(0 0 0 / 51%);border-radius: 999px;padding: 5px 10px;color: #fff;">暂无优惠</span>` if(this.isHasCoupon){ html = `<span style="background: rgb(253 2 57);border-radius: 999px;padding: 5px 10px;color: #fff;">有券:减${this.couponInfo.couponAmount}元</span>` } return html } get loadingElement(){ const div = document.createElement('div'); div.style = 'position: absolute;top: 10px;right: 10px;z-index: 99999999;font-size: 12px;'; div.innerHTML = ` <span style="background: rgb(0 0 0 / 51%);border-radius: 999px;padding: 5px 10px;color: #fff;">正在搜索优惠</span> `; return div; } constructor(element,platform){ super(platform); this.addCouponElement(element) } async addCouponElement(element){ try { //获取商品ID和优惠券API链接 if(this.platform == 'taobao'||this.platform == 'tmallcs'){ const href = element.getAttribute('href'); this.goodsId = Utils.getQueryParam('id',href)||null; const shortUrl = await this.getTbShortUrl(this.goodsId); console.log(shortUrl) this.couponApiUrl = API_DOMAIN + '/api/coupon/search?platform=taobao' + '&id=' + shortUrl }else if(this.platform === 'jd'){ const href = element.getAttribute('href'); this.goodsId = Utils.getUrlid(href)||null; this.couponApiUrl = API_DOMAIN + '/api/coupon/search?platform=jd' + '&id=' + this.goodsId; } element.style.position = 'relative'; //添加优惠券节点 this.appendCouponElement(element,'beforeend'); //获取商品优惠券 this.couponInfo = await this.getCouponInfo(); } catch (error) { console.log(error) //更新无佣金html this.updateCouponErrorHtml() console.log(error.message) } } } async function getInitData(){ const request = ()=>{ return new Promise((resolve, reject) => { fetch(API_DOMAIN + '/api/coupon/init',{ method:'GET', mode:'cors', }).then(r=>r.json()).then(response=>{ if(response.code === 1){ resolve(response.data) }else{ resolve(null) } }).catch(err=>{ resolve(null) }) }) } const _initData = await request(); _initData&&(initData.coupon = {..._initData}); } async function detailCouponInit(platform = 'taobao'){ await getInitData(); new DetailCoupon(platform); //移除节点 if(initData.coupon.blackElement instanceof Array && initData.coupon.blackElement.length > 0){ const blackElement = initData.coupon.blackElement; blackElement.forEach(item => { Utils.monitorElement(item).then(selector=>{ selector.remove() }) }) } } async function searchCouponInit(platform = 'taobao'){ await getInitData(); if(!(initData.coupon?.[platform]?.searchGoodsCardElement instanceof Array)||initData.coupon?.[platform]?.searchGoodsCardElement.length === 0) return //class数组 const clss = initData.coupon[platform].searchGoodsCardElement; //监听商品卡片 setInterval(()=>{ //遍历class数组 for (let i = 0; i < clss.length; i++) { const elements = document.querySelectorAll(clss[i]); if(elements&&elements.length > 0){ Array.from(elements).forEach(element=>{ if(element.classList.contains('zhihu-coupon-added')) return; //添加class标记 element.classList.add('zhihu-coupon-added'); new SearchCoupon(element,platform); }) } } },1500) } async function zhihuWenkuInit(){ sessionStorage.setItem('zhihu_sign',true); } //网址匹配 const siteMap = [ { match:['item.taobao.com/item.htm.*'], platform:'taobao', initFunc:detailCouponInit }, { match:['detail.tmall.com/item.htm.*','detail.tmall.hk/hk/item.htm.*'], platform:'tmall', initFunc:detailCouponInit }, { match:['item.jd.com/.*','npcitem.jd.hk/.*','item.yiyaojd.com/.*'], platform:'jd', initFunc:detailCouponInit }, { match:['s.taobao.com/search.*','suning.tmall.com/category.*'], platform:'taobao', initFunc:searchCouponInit }, { match:['pages.tmall.com/wow/an/cs/search.*'], platform:'tmallcs', initFunc:searchCouponInit }, { match:['search.jd.com/Search.*','list.jd.com/list.html.*','mall.jd.com/view_search.*'], platform:'jd', initFunc:searchCouponInit }, { match:['wenku.zhihupe.com/tool/index.*','wenku.zhihupe.com/#.*'], initFunc:zhihuWenkuInit } ] //生成正则表达式 function createReg(arr){ return new RegExp(arr.join('|')) } //根据网址匹配 for (const site of siteMap) { let reg = createReg(site.match) let host = window.location.hostname + window.location.pathname let result = reg.test(host) if(result){ let platform = site.platform||''; return site.initFunc(platform); } } // Your code here... })();;