您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
将bilibili关注从一个账号转移到另一个账号
// ==UserScript== // @name Bilibili关注迁移 // @namespace http://tampermonkey.net/ // @version 0.1 // @description 将bilibili关注从一个账号转移到另一个账号 // @author Todd // @match https://space.bilibili.com/*/fans/follow* // @icon https://www.google.com/s2/favicons?sz=64&domain=bilibili.com // @grant none // @license MIT // ==/UserScript== const title_seletor = "#page-follows > div > div.follow-main > div.follow-header.follow-header-info > div"; let WaitForLoaded = (parentNode, checkFuntion) => { let option = { 'childList': true, 'subtree': true }; let promise = new Promise((resolve, reject) => { let mo = new MutationObserver((mutations, obs) => { try { if (checkFuntion(mutations)) { resolve(obs); } } catch (e) { reject(e); } }) mo.observe(parentNode, option); }) return promise; } function getUid() { let regExp = new RegExp('(?<=https://space.bilibili.com/)[\\d]+') let url = window.location.href; return regExp.exec(url)[0]; } async function getFollowListPromise(uid, pn) { let url = `https://api.bilibili.com/x/relation/followings?vmid=${uid}&pn=${pn}&ps=50` let promise = fetch(url, { "headers": { "accept": "*/*", "accept-language": "zh-CN,zh;q=0.9", "sec-ch-ua": "\"Not_A Brand\";v=\"99\", \"Google Chrome\";v=\"109\", \"Chromium\";v=\"109\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"Windows\"", "sec-fetch-dest": "script", "sec-fetch-mode": "no-cors", "sec-fetch-site": "same-site" }, "referrer": "https://space.bilibili.com/5919189/fans/follow?spm_id_from=333.788.0.0", "referrerPolicy": "no-referrer-when-downgrade", "body": null, "method": "GET", "mode": "cors", "credentials": "include" }); let res = await promise; let body = await res.json(); let follow_array = body.data.list; return follow_array.map((val) => val.mid).flat(); } let ALL_COUNT = 0; let CUR_COUNT = 0; async function getFollowPromise(id, csrf) { await fetch("https://api.bilibili.com/x/relation/modify", { "headers": { "accept": "application/json, text/plain, */*", "accept-language": "zh-CN,zh;q=0.9", "content-type": "application/x-www-form-urlencoded", "sec-ch-ua": "\"Not_A Brand\";v=\"99\", \"Google Chrome\";v=\"109\", \"Chromium\";v=\"109\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"Windows\"", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-site" }, "body": `fid=${id}&act=1&csrf=${csrf}`, "method": "POST", "mode": "cors", "credentials": "include" }); console.log(`Finished ${++CUR_COUNT} of ${ALL_COUNT}`) } async function backup() { let uid = getUid(); let follow_count_selector = '#page-follows > div > div.follow-sidenav > div.nav-container.follow-container > div.be-scrollbar.follow-list-container.ps > ul > li.follow-item.cur > span.num' let follow_count = document.querySelector(follow_count_selector).innerHTML follow_count = parseInt(follow_count); let loop_count = Math.ceil(follow_count / 50); let promise_array = []; for (let i = 1; i <= loop_count; i++) { promise_array.push(getFollowListPromise(uid, i)) } let follows = await Promise.all(promise_array); await navigator.clipboard.writeText(follows.toString()); alert("所有关注已复制至剪切板,粘贴至还原按钮弹出的对话框即可"); } async function restore() { let follow_id = prompt(); let follow_id_array = follow_id.split(","); let cookie = document.cookie; let reg = /(?<=bili_jct=)(.+?)(?=;)/ let csrf = reg.exec(cookie)[0]; ALL_COUNT = follow_id_array.length; console.log(csrf); console.log(follow_id_array); let id = setInterval(async ()=>{ await getFollowPromise(follow_id_array.pop(), csrf); if(CUR_COUNT >= ALL_COUNT){ clearInterval(id); } }, 1000); //1秒发送一次关注请求 //await Promise.all(promise_array); } function insertBtn() { let title = document.querySelector(title_seletor); let backup_btn = document.createElement("button"); let restore_btn = document.createElement("button"); backup_btn.style.fontSize = "12px"; restore_btn.style.fontSize = "12px"; backup_btn.onclick = backup; restore_btn.onclick = restore; backup_btn.innerHTML = "备份"; restore_btn.innerHTML = "还原"; title.appendChild(backup_btn); title.appendChild(restore_btn); const search_seletor = "#page-follows > div > div.follow-main > div.follow-header.follow-header-info > div > div" document.querySelector(search_seletor).style.order = 1; } async function main() { let obs = await WaitForLoaded(document.body, () => { return document.querySelectorAll(title_seletor).length > 0 }); obs.disconnect(); insertBtn(); } main();