// ==UserScript==
// @name 网购省钱小助手:自动查询京东、淘宝、聚划算、天猫等隐藏的优惠券;自动历史价格查询;界面优化等;低侵入、持续维护更新😈
// @namespace coupon_namespace_20230625
// @version 1.0.2
// @description 用电脑端访问淘宝、天猫、京东等不会主动领取优惠券,此脚本可以把只有APP端能看到的或本来就隐藏的大额优惠券给查询出来,有券不领非好汉~ 脚本采用低侵入形式,不会破坏网页结构,大家可以放心使用
// @author 爱画画的猫
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABFFJREFUWEfFl11oHFUUx/9nZne7s7PZpDUfmkANWKoQq5VqlVJUBK2BVI1QqILpLNaUlqxpRSLqQ9uQILbUNNltpImSDbXQKlJMIkR9qC0UEaJV8MVSUKs2iSZp2nRnN/txr0yanezMzmQ3G6Hn8Z5zz/nd83HnDuE2CxUS/59j27y+lKeCcaFCdKZuJuKuce/ej8YL8ZU3QCTYUEsQagFeC9Aay2CEQXA6yxk7Lzf3/5APUE6AWMhfx8AbwbE1H4dpGwL1MMZ6coEsCqAG/e8DvGUpgc22nOGg3Bw+YOfDFkANKSPg2LCc4AvZwJdSIFxn5csSQA0pv4Gj+v8InvZhl4ksgGhI6eMcil1wobwaYvWDWWp2YxJs7DL49JgtNxEapKbwiUwDA8Bcw3E+aOdBvHsdXFvfsA3A/v0LsyfeBVyCnc1VyeV6mHb1jGaUZ8FWDSkDi3W7c+PzcGx8AbGOZssA7n2diHXuBYv8DfJ5LW3MpdAzEAv6tzDw4cXqngaI7H48y0xc+xDmADqakbp0EXRnKeiOYit3VyVRup/2fHhNU+oAkS6lnQjvmHc4ap4EyfOOOIfj0XokhvosOZ11foOOTV0Bu/G7hS1t9wT6ThsAokHlFw7UZFo7N2+HY/2WZQ3D7Mn3wKZ+BWih3Qj4WAqEd+oA2t3uZfKMOdKK+rcgVN23LAAtW/FvT0GoLANcznlffMQT6H9EB4h17biHEV02R3I9uwfimjm7giV+qgOJc2fmggtV5YDHrfn60xMIr9YB1E7/Jgj8gjmK84lX4Fj3lGE5+f1XmA23WwJJb/dCWH2vQTfbux/JH8/eWhMIVFkOKvbGPYHwCh1gtrvhgVRK+DkLYH7szOupSz9ZAohr12etp6ciU0Hlq6Jy6xceHeDm0Z0VgpjMusK002tZWI5EWxvARo2TQIKQkrvPOQxToAYVbg6k1V/rg+VkQG15Dnxm2uhCdk94j3xTZgSwuAW1CdAmIVOW2gNWlxYVyRfkw8ObTRnw7wP4B4ZaraqC++W2giugnVzLgFmotLhJbhs6ZgCIdO7YQAKNGACkIrhf7SoYQKu91gMGkaVp75GvV6bXDF/DaNB/nGvPrwyRmqyv3XyotGmJdbxuNK0o6fIeHNS/ZgYAqyw4H3sJYs0mkGT9dbMD4ZNjiH8eQvLied2EfPKkfGi41JBlswM16H8T4If19RQDuzIKqLF8Dm1v4xAhFHtf9LQPnVkUQFNGOpUDJGC/bhiL34JIJAuGEH2yIh0a7s9qSDuPalDZBuDTtJ7PqOAaxFJFILDSkkZf60Cv1dYcz/I5iKMAKrXNfOo6+OhE3ghU5LmGspIGueX0kN2mnD8m/HjjXWosvosEvKaB8PFJ8AnTzWb2LkvXSXJ/IrcNNOWizQmgl6B798poKvYMgT/N/hit5/GED4mkA0ScHGKci0IUTud3olv8TGq1eTJZ0OQNkOskhepvO8B/AOOGMHhVlZkAAAAASUVORK5CYII=
// @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/*
// @exclude *://login.taobao.com/*
// @exclude *://uland.taobao.com/*
// @exclude *://pages.tmall.com/*
// @require https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.2.1/jquery.min.js
// @require https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery.qrcode/1.0/jquery.qrcode.min.js
// @connect tt.shuqiandiqiu.com
// @connect j.jiayoushichang.com
// @grant GM_openInTab
// @grant GM.openInTab
// @grant GM_getValue
// @grant GM.getValue
// @grant GM_setValue
// @grant GM.setValue
// @grant GM_xmlhttpRequest
// @grant GM.xmlHttpRequest
// @license AGPL License
// @charset UTF-8
// @run-at document-idle
// ==/UserScript==
(function () {
'use strict';
/**
* 公共的方法
*/
class CommonTools{
request(mothed, url, param){
return new Promise(function(resolve, reject){
GM_xmlhttpRequest({
url: url,
method: mothed,
data:param,
onload: function(response) {
var status = response.status;
var playurl = "";
if(status==200||status=='200'){
var responseText = response.responseText;
resolve({"code":"success", "result":responseText});
}else{
reject({"code":"error", "result":null});
}
}
});
})
}
randomNumber(){
return Math.ceil(Math.random()*100000000);
}
getPlatform(url = window.location.href){
let platform = "";
if(url.indexOf("detail.tmall")!=-1 || url.indexOf("tmall.hk")!=-1){
platform = "tmall";
}else if(url.indexOf("taobao.com")!=-1 || url.indexOf("maiyao.liangxinyao.com")!=-1){
platform = "taobao";
}else if(url.indexOf("jd.com")!=-1 || url.indexOf("npcitem.jd.hk")!=-1 || url.indexOf("yiyaojd.com")!=-1){
platform = "jd";
}
return platform;
}
getParamterQueryUrl(text, tag) { //查询GET请求url中的参数
if(text.indexOf("?")!=-1){ //选取?后面的字符串,兼容window.location.search,前面的?不能去掉
var textArray = text.split("?");
text = "?"+textArray[textArray.length-1];
}
var t = new RegExp("(^|&)" + tag + "=([^&]*)(&|$)");
var a = text.substr(1).match(t);
if (a != null){
return a[2];
}
return "";
}
getEndHtmlIdByUrl(url){
if(url.indexOf("?")!=-1){
url = url.split("?")[0]
}
if(url.indexOf("#")!=-1){
url = url.split("#")[0]
}
var splitText = url.split("/");
var idText = splitText[splitText.length-1];
idText = idText.replace(".html","");
return idText;
}
getElementAsync(selector, allowEmpty = true, delay=200){
return new Promise((resolve,reject) =>{
let totalDelay = 0;
let elementInterval = setInterval(()=>{
if(totalDelay >= 3000){ //总共检查3s,如果还是没找到,则返回
reject(false);
clearInterval(elementInterval);
}
let element = document.querySelector(selector);
let result = allowEmpty ? !!element : (!!element && !!element.innerHTML);
if(result){
clearInterval(elementInterval);
resolve(element);
}else{
totalDelay += delay;
}
}, delay);
});
}
}
/**
* 优惠券相关功能
*/
class Coupon{
platforms = ["detail.tmall.com", "item.taobao.com", "item.jd.com", "item.yiyaojd.com", "npcitem.jd.hk", "detail.tmall.hk"];
constructor(){
this.commonTools = new CommonTools();
}
isRun(){
for(var i=0; i<this.platforms.length;i++){
if(window.location.host.indexOf(this.platforms[i])!=-1){
return true;
}
}
return false;
}
filterName(str){
if(!str) return "";
str = str.replace(/\t/g,"");
str = str.replace(/\r/g,"");
str = str.replace(/\n/g,"");
return encodeURIComponent(str)
}
async getGoodsData(platform){
var goodsId = "";
var goodsName = "";
const href = window.location.href;
if(platform=="taobao"){
goodsId = this.commonTools.getParamterQueryUrl(window.location.search, "id");
try{
const titleObj = await this.commonTools.getElementAsync("[class='tb-main-title']", false);
goodsName = titleObj.getAttribute("data-title");
if(!goodsName){
goodsName = titleObj.textContent;
}
}catch(e){}
}else if(platform=="tmall"){
goodsId = this.commonTools.getParamterQueryUrl(window.location.search, "id");
try{
const titleObj = await this.commonTools.getElementAsync("[class^='ItemHeader--mainTitle--']", false);
goodsName = titleObj.textContent;
}catch(e){}
}else if(platform=="jd"){
goodsId = this.commonTools.getEndHtmlIdByUrl(href);
try{
const titleObj = await this.commonTools.getElementAsync("[class='sku-name']", false);
goodsName = titleObj.textContent;
}catch(e){}
}
const data = {"goodsId":goodsId, "goodsName":this.filterName(goodsName)};
return data;
}
randomSpmValue(){
$("meta[name='data-spm']").each(function(){
var max = 5000;
var min = 1000;
var randomValue = Math.floor(Math.random() * (max - min + 1) ) + min;
var randomLetter = String.fromCharCode(Math.floor( Math.random() * 26) + "a".charCodeAt(0));
$(this).attr("content", randomValue+randomLetter);
});
$("meta[name='spm-id']").each(function(){
var max = 5000;
var min = 1000;
var randomValue = Math.floor(Math.random() * (max - min + 1) ) + min;
var randomLetter = String.fromCharCode(Math.floor( Math.random() * 26) + "a".charCodeAt(0));
$(this).attr("content", randomValue+randomLetter);
});
$("body").find("*").each(function(){
$(this).removeAttr("data-spm-anchor-id");
$(this).removeAttr("data-spm");
});
}
runAliDeceptionSpm(){
const host = window.location.host;
if(host.indexOf("aliyun.com")!=-1 || host.indexOf("taobao.com")!=-1 || host.indexOf("tmall.com")!=-1){
this.randomSpmValue();
setInterval(()=>{
this.randomSpmValue();
}, 2000);
}
}
async createCouponHtml(platform, goodsId, goodsName){
if(!platform || !goodsId) return;
const goodsCouponUrl = "http://tt.shuqiandiqiu.com/api/coupon/discover?no=5&v=1.0.2&pl="+platform+"&id="+goodsId+"&qu="+goodsName;
const goodsPrivateUrl = "http://tt.shuqiandiqiu.com/api/private/change/coupon?no=5&v=1.0.2&platform="+platform+"&id=";
try{
const data = await this.commonTools.request("GET", goodsCouponUrl, null);
if(data.code=="success" && !!data.result){
const result = JSON.parse(data.result).data;
if(!result || result==="null" || !result.css || !result.html || !result.handler){
return;
}
const cssText = result.css, htmlText = result.html, handler = result.handler, templateId = result.templateId;
if(!cssText || !htmlText || !handler){
return;
}
$("body").prepend("<style>"+cssText+"</style>");
// 添加HTML
const handlers = handler.split("@");
for(var i=0; i<handlers.length; i++){
var $handler = $(""+handlers[i]+"");
if(platform=="taobao"){
$handler.parent().after(htmlText);
}else if(platform=="tmall"){
$handler.parent().after(htmlText);
}else if(platform=="jd"){
$handler.after(htmlText);
}
}
const $template = $("#"+templateId);
if($template.length == 0){
return;
}
const couponElementA = $template.find("a[name='cpShUrl']");
couponElementA.unbind("click").bind("click", ()=>{
event.stopPropagation();
event.preventDefault();
let couponId = $template.data("id");
if(!!couponId){
this.commonTools.request("GET", goodsPrivateUrl+couponId, null).then((resutData2)=>{
if(resutData2.code==="success" && !!resutData2.result){
let url = JSON.parse(resutData2.result).url;
if(!!url) GM_openInTab(url, {active:true});
}
});
}
});
setInterval(()=>{
$template.find("*").each(function(){
$(this).removeAttr("data-spm-anchor-id");
});
},400);
//canvas画二维码
var $canvasElement = $("#ca"+templateId);
if($canvasElement.length == 0){
return;
}
let couponId = $template.data("id");
this.commonTools.request("GET", goodsPrivateUrl+couponId, null).then((resutData2)=>{
if(resutData2.code==="success" && !!resutData2.result){
let img = JSON.parse(resutData2.result).img;
if(!!img){
var canvasElement = document.getElementById("ca"+templateId);
var cxt = canvasElement.getContext("2d");
var imgData = new Image();
imgData.src = img;
imgData.onload=function(){
cxt.drawImage(imgData, 0, 0, imgData.width, imgData.height);
}
}
}
});
}
}catch(e){}
}
showGoodsQRcode(platform){
if(platform==="jd"){ //京东不需要这个方法
return;
}
const elementId = Math.ceil(Math.random()*100000000)+"qrcode";
const width = 130;
const title = platform=="jd" ? "京东APP扫码查看此商品":"淘宝APP扫码查看此商品";
const text = platform=="jd" ? window.location.href : window.location.href.split("?")[0] + "?id="+this.commonTools.getParamterQueryUrl(window.location.search, "id");
var html = `
<div style="position:fixed;right:40px;bottom:10px;z-index:99999999;padding:5px;background-color:#F2F2F2;border-radius:3px;">
<div style='font-size:12px;'>`+title+`</div>
<div style='width:`+width+`px;height:`+width+`px;margin:0px auto;' id='`+elementId+`'></div>
</div>
`;
$("body").append(html);
jQuery('#'+elementId).qrcode({
render: "canvas",
width: width,
height: width,
foreground: "#000",
background: "#FFF",
text: text
});
console.log("text", text);
};
comparePrice(){ //比价开发中.....
}
async start(){
if(this.isRun()){
this.runAliDeceptionSpm();
const platform = this.commonTools.getPlatform();
if(!!platform){
this.showGoodsQRcode(platform);
const goodsData = await this.getGoodsData(platform);
this.createCouponHtml(platform, goodsData.goodsId, goodsData.goodsName);
}
if(platform=="tmall"){ //tmall如果sku太多就折叠
const skuItemWrapper = await this.commonTools.getElementAsync("[class='skuItemWrapper']", false);
if(skuItemWrapper != null){
const { style } = skuItemWrapper;
style.maxHeight = "400px";
style.overflow = "auto";
}
}
}
}
}
/**
* 优惠券搜索
* 部分代码借鉴 洪皓儿 的代码,已经获得原作者授权使用
* 原脚本地址:https://greasyfork.org/zh-CN/scripts/428266
*/
class SearchPageObject{
intervalIsRunComplete = true; //定时任务一个循环是否完成
constructor(){
this.commonTools = new CommonTools();
}
pickupSearchElements(){ //收集列表的元素
const selectorElementList = new Array();
const url = window.location.href;
if(url.indexOf("://s.taobao.com/search")!=-1 || url.indexOf("://s.taobao.com/list")!=-1) { //淘宝搜索页面
selectorElementList.push({"element":".items >.item", "page":"taobao"});
selectorElementList.push({"element":".Content--content--sgSCZ12 .Card--doubleCardWrapper--L2XFE73", "page":"taobao_new"});
selectorElementList.push({"element":".Content--content--sgSCZ12 .Card--listCardWrapper--ax09OfT", "page":"taobao_new"});
selectorElementList.push({"element":".Content--content--sgSCZ12 .Card--doubleCardWrapperMall--uPmo5Bz", "page":"taobao_new"});
selectorElementList.push({"element":".Content--content--sgSCZ12 .Card--listCardWrapperMall--E3jI8L4", "page":"taobao_new"});
}else if(url.indexOf("taobao.com/category")!=-1){ //淘宝店铺分类
selectorElementList.push({"element":"dl.item", "page":"taobao_category"});
}else if(url.indexOf("taobao.com/search.htm")!=-1){ //淘宝店铺搜索
selectorElementList.push({"element":"dl.item", "page":"taobao_shop_search"});
}
else if (url.indexOf("://list.tmall.com/search_product.htm")!=-1 || url.indexOf("://list.tmall.com//search_product.htm")!=-1
|| url.indexOf("://list.tmall.com/coudan/search_product.htm")!=-1) { //天猫超市
selectorElementList.push({"element":".product", "page":"tmall_chaoshi_search"});
selectorElementList.push({"element":".chaoshi-recommend-list .chaoshi-recommend-item", "page":"tmall_chaoshi_search_new"}); //新天猫超市
}else if (url.indexOf("//list.tmall.hk/search_product")!=-1) { //天猫国际
selectorElementList.push({"element":"#J_ItemList .product", "page":"tmall_hk"});
}else if(url.indexOf("tmall.com/category-")!=-1){ //天猫分类
selectorElementList.push({"element":"#J_ShopSearchResult dl.item", "page":"tmall_category"});
}else if(url.indexOf("tmall.com/category-")!=-1){ //天猫旗舰店分类
selectorElementList.push({"element":"#J_ShopSearchResult dl.item", "page":"tmall_category"});
}else if(url.indexOf(".tmall.com/shop/view_shop.htm")!=-1){ //天猫旗舰全部展示
selectorElementList.push({"element":"dl.item", "page":"tmall_shop_01"});
}else if(url.indexOf(".tmall.com/search.htm")!=-1){
selectorElementList.push({"element":"dl.item", "page":"tmall_shop_search"});
}
else if(url.indexOf("//maiyao.liangxinyao.com/shop/view_shop.htm")!=-1
|| url.indexOf("//maiyao.liangxinyao.com/search.htm")!=-1
|| url.indexOf("//maiyao.liangxinyao.com/category")!=-1){ //阿里大药房
selectorElementList.push({"element":"#J_ShopSearchResult dl.item", "page":"ali_yao"});
}
else if (url.indexOf("//search.jd.com/Search")!=-1) { //京东搜索
selectorElementList.push({"element":"#J_goodsList li.gl-item", "page":"jd"});
}else if(url.indexOf("//search.jd.hk/Search")!=-1){ //京东国际
selectorElementList.push({"element":"#plist li.gl-item", "page":"jd_hk"});
}else if(url.indexOf("//mall.jd.com/view_search")!=-1){ //京东大药房
selectorElementList.push({"element":"li.jSubObject", "page":"jd_yao"});
}
return selectorElementList;
}
createAllElementHtml(elementData){ //为所有的商品创建提示
const self = this;
$(elementData.element).each(function(){ //遍历所有的商品框
self.createOneElementHtml($(this), elementData);
});
self.intervalIsRunComplete = true;
}
/**
* 为商品box添加有券提醒
* @param {Object} $element 每一个商品box
* @param {Object} elementData id and page
*/
async createOneElementHtml($element, elementData){ //查询到每个商品list
if($element.attr("completebox")){ //当存在时,说明已经处理过了
return;
}
$element.css("position","relative");
var page = elementData.page;
var goodsDetailUrl = null;
if(page==="taobao"){
goodsDetailUrl = $element.find("a[id^='J_Itemlist_TLink_']").attr("href");
}else if(page==="taobao_new"){
let href = $element.attr("href");
goodsDetailUrl = href.indexOf("http") == -1 ? (location.protocol + href) : href;
}else if(page==="taobao_category"){
goodsDetailUrl = $element.find(".J_TGoldData").attr("href");
}else if(page==="taobao_shop_search"){
goodsDetailUrl = $element.find(".J_TGoldData").attr("href");
}else if(page==="ali_yao"){
goodsDetailUrl = $element.find(".J_TGoldData").attr("href");
}else if(page==="tmall_chaoshi_search"){
let href = $element.find("div.product-img").find("a").attr("href");
goodsDetailUrl = href.indexOf("http") ==-1 ? (location.protocol + href) : href;
}else if(page==="tmall_chaoshi_search_new"){
let href = !!$element.attr("href")?$element.attr("href"):$element.find("a").attr("href");
goodsDetailUrl = href.indexOf("http") ==-1 ? (location.protocol + href) : href;
}else if(page==="tmall_hk"){
goodsDetailUrl = $element.find("a.productImg").attr("href");
}else if(page==="tmall_category"){
goodsDetailUrl = $element.find(".J_TGoldData").attr("href");
}else if(page==="tmall_shop_01"){
goodsDetailUrl = $element.find("dt.photo").find("a").attr("href");
}else if(page==="tmall_shop_search"){
goodsDetailUrl = $element.find(".J_TGoldData").attr("href");
}
else if(page==="jd"){
goodsDetailUrl = $element.find("div.p-img").find("a").attr("href");
}else if(page==="jd_hk"){
goodsDetailUrl = $element.find("div.p-img").find("a").attr("href");
}else if(page==="jd_yao"){
goodsDetailUrl = $element.find("div.jPic").find("a").attr("href");
}
if(!goodsDetailUrl){
return;
}
// console.log(goodsDetailUrl);
var analysisData = null;
if(page==="jd" || page==="jd_hk"){
var jdId = this.commonTools.getEndHtmlIdByUrl(goodsDetailUrl);
if(!!jdId) analysisData = {"id":jdId, "platform":"jd"};
}else{
var platform = this.commonTools.getPlatform(goodsDetailUrl);
var id = this.commonTools.getParamterQueryUrl(goodsDetailUrl, "id");
if(platform && id){
analysisData = {"id":id, "platform":platform};
}
}
if(!analysisData){
return;
}
try{
const searchUrl = "http://j.jiayoushichang.com/api/ebusiness/coupon/exist/"+analysisData.platform+"?id="+analysisData.id;
const data = await this.commonTools.request("GET", searchUrl, null);
if(data.code=="success" && !!data.result){
const tip = JSON.parse(data.result).tip;
if(tip){
$element.append(tip);
}
}
}catch(e){}
$element.attr("completebox","true");
}
searchPage(selectorElementList){
if(!this.intervalIsRunComplete){
return;
}
selectorElementList.forEach((elementData)=>{
if(!!elementData){
this.createAllElementHtml(elementData);
}
});
}
start(){
const selectorElementList = this.pickupSearchElements();
setInterval(()=>{
this.searchPage(selectorElementList);
}, 500);
};
}
(new Coupon()).start();
(new SearchPageObject()).start();
})();