Microsoft Bing Rewards每日任务脚本

自动完成微软Rewards每日搜索任务,每次运行时获取抖音/微博/哔哩哔哩/百度/头条热门词,避免使用同样的搜索词被封号。改编自“怀沙2049”制作的v3.0.0版

目前为 2024-09-09 提交的版本。查看 最新版本

// ==UserScript==
// @name         Microsoft Bing Rewards每日任务脚本
// @version      3.0.1
// @description  自动完成微软Rewards每日搜索任务,每次运行时获取抖音/微博/哔哩哔哩/百度/头条热门词,避免使用同样的搜索词被封号。改编自“怀沙2049”制作的v3.0.0版
// @author       honguangli
// @match        https://www.bing.com/*
// @match        https://cn.bing.com/*
// @license      GNU GPLv3
// @icon         https://www.bing.com/favicon.ico
// @connect      gumengya.com
// @run-at       document-end
// @grant        GM_registerMenuCommand
// @grant        GM_addStyle
// @grant        GM_openInTab
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_xmlhttpRequest
// @namespace    https://greasyfork.org/zh-CN/scripts/477107
// ==/UserScript==

const url = 'https://cn.bing.com/search';
const max_rewards = 35; //重复执行的次数
//每执行4次搜索后插入暂停时间,解决账号被监控不增加积分的问题
const pause_time = 5000; // 暂停时长建议为10分钟(600000毫秒=10分钟)

//默认搜索词,热门搜索词请求失败时使用
const default_search_words = ["盛年不重来,一日难再晨", "千里之行,始于足下", "少年易学老难成,一寸光阴不可轻", "敏而好学,不耻下问", "海内存知已,天涯若比邻","三人行,必有我师焉",
    "莫愁前路无知已,天下谁人不识君", "人生贵相知,何用金与钱", "天生我材必有用", "海纳百川有容乃大;壁立千仞无欲则刚", "穷则独善其身,达则兼济天下", "读书破万卷,下笔如有神",
    "学而不思则罔,思而不学则殆", "一年之计在于春,一日之计在于晨", "莫等闲,白了少年头,空悲切", "少壮不努力,老大徒伤悲", "一寸光阴一寸金,寸金难买寸光阴","近朱者赤,近墨者黑",
    "吾生也有涯,而知也无涯", "纸上得来终觉浅,绝知此事要躬行", "学无止境", "己所不欲,勿施于人", "天将降大任于斯人也", "鞠躬尽瘁,死而后已", "书到用时方恨少","天下兴亡,匹夫有责",
    "人无远虑,必有近忧","为中华之崛起而读书","一日无书,百事荒废","岂能尽如人意,但求无愧我心","人生自古谁无死,留取丹心照汗青","吾生也有涯,而知也无涯","生于忧患,死于安乐",
    "言必信,行必果","读书破万卷,下笔如有神","夫君子之行,静以修身,俭以养德","老骥伏枥,志在千里","一日不读书,胸臆无佳想","王侯将相宁有种乎","淡泊以明志。宁静而致远,","卧龙跃马终黄土"]
//{weibohot}微博热搜榜//{douyinhot}抖音热搜榜/{zhihuhot}知乎热搜榜/{baiduhot}百度热搜榜/{toutiaohot}今日头条热搜榜/
const keywords_source = ['BaiduHot','TouTiaoHot','DouYinHot', 'WeiBoHot'];
const random_keywords_source = keywords_source[Math.floor(Math.random() * keywords_source.length)]
const current_source_index = 0; // 当前搜索词来源的索引

const keyCount = "cnt" // 计数器key值
let scrollIntervalId = null; // 模拟滚动定时器id
let searchTimeoutId = null; // 查询定时器id

// 定义菜单命令:开始
const menu1 = GM_registerMenuCommand('开始', function () {
    GM_setValue(keyCount, 0); // 将计数器重置为0
    exec();
}, 'o');

// 定义菜单命令:停止
const menu2 = GM_registerMenuCommand('停止', function () {
    GM_setValue(keyCount, max_rewards + 1); // 将计数器设置为超过最大搜索次数,以停止搜索
    clearInterval(scrollIntervalId);
    clearTimeout(searchTimeoutId);
}, 'o');

exec();

function exec() {
    const cnt = GM_getValue(keyCount);
    if (cnt == null || cnt < 0 || cnt >= max_rewards) {
        return
    }

    GM_setValue(keyCount, cnt + 1);

    douyinhot_dic().then(names => {
        const delay = Math.floor(Math.random() * 20000) + 10000 + (cnt % 5 === 0 ? pause_time : 0);
        const tt = document.getElementsByTagName("title")[0];
        tt.innerHTML = "[" + cnt + " / " + max_rewards + "][" + Math.ceil(delay / 1000) + "秒后跳转] " + tt.innerHTML; // 在标题中显示当前搜索次数

        // 模拟滚动,提高识别率
        scrollIntervalId = setInterval(function() {
            window.scrollTo(0, Math.floor(Math.random() * 500))
        }, 500)

        searchTimeoutId = setTimeout(function () {
            const nowtxt = AutoStrTrans(names[cnt]); // 获取当前搜索词
            const randomString = generateRandomString(4); //生成4个长度的随机字符串
            const randomCvid = generateRandomString(32); //生成32位长度的cvid

            clearInterval(scrollIntervalId);
            location.href = url + "?q=" + encodeURI(nowtxt) + "&form=" + randomString + "&cvid=" + randomCvid; // 在Bing搜索引擎中搜索
        }, cnt === 0 ? 0 : delay);
    }).catch(error => {
        console.error(error);
    });
}

/**
 * 尝试从多个搜索词来源获取搜索词,如果所有来源都失败,则返回默认搜索词。
 * @returns {Promise<string[]>} 返回搜索到的name属性值列表或默认搜索词列表
 */
async function douyinhot_dic() {
    while (current_source_index < keywords_source.length) {
        const source = keywords_source[current_source_index]; // 获取当前搜索词来源
        try {
            const response = await fetch("https://api.gumengya.com/Api/" + source); // 发起网络请求
            if (!response.ok) {
                throw new Error('HTTP error! status: ' + response.status); // 如果响应状态不是OK,则抛出错误
            }
            const data = await response.json(); // 解析响应内容为JSON

            if (data.data.some(item => item)) {
                // 如果数据中存在有效项
                // 提取每个元素的title属性值
                const names = data.data.map(item => item.title);
                return names; // 返回搜索到的title属性值列表
            }
        } catch (error) {
            // 当前来源请求失败,记录错误并尝试下一个来源
            console.error('搜索词来源请求失败:', error);
        }

        // 尝试下一个搜索词来源
        current_source_index++;
    }

    // 所有搜索词来源都已尝试且失败
    console.error('所有搜索词来源请求失败');
    return default_search_words; // 返回默认搜索词列表
}

// 自动将字符串中的字符进行替换
function AutoStrTrans(st) {
    let yStr = st; // 原字符串
    let rStr = ""; // 插入的混淆字符,可以自定义自己的混淆字符串
    let zStr = ""; // 结果字符串
    let prePo = 0;
    for (let i = 0; i < yStr.length;) {
        let step = parseInt(Math.random() * 5) + 1; // 随机生成步长
        if (i > 0) {
            zStr = zStr + yStr.substr(prePo, i - prePo) + rStr; // 将插入字符插入到相应位置
            prePo = i;
        }
        i = i + step;
    }
    if (prePo < yStr.length) {
        zStr = zStr + yStr.substr(prePo, yStr.length - prePo); // 将剩余部分添加到结果字符串中
    }
    return zStr;
}

// 生成指定长度的包含大写字母、小写字母和数字的随机字符串
function generateRandomString(length) {
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    let result = '';
    const charactersLength = characters.length;
    for (let i = 0; i < length; i++) {
        // 从字符集中随机选择字符,并拼接到结果字符串中
        result += characters.charAt(Math.floor(Math.random() * charactersLength));
    }
    return result;
}