// ==UserScript==
// @name B站動態導航 (歸檔員自用)
// @namespace http://yuhang0000.github.io/
// @version v1.8_2025-3-22
// @description 能導航到指定日期的動態,僅對 https://space.bilibili.com/<你UID>/dynamic/ 作用,僅歸檔員自用。
// @author 欲行肆灵
// @match https://space.bilibili.com/*
// @grant none
// @license GPLv3
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7EAAAOxAGVKw4bAAACnklEQVRYR+2XX0hTURzHv9edXVuNNaFhm+CLiBXh8qXaUGRBD+YCX8oSwerm34cG+RKxMGlILxMEwYxuTVCazxV7S8Q0eskUscboIWOzWpDWck5n9rDuzXO3dbu4raA+cGHn+/ve8/vew93ZGfBXolIRNPd40P/kAzrcXmi0OqlFFo1Whw63F/2TYTT3eKBSEaklPZV1TRia3xQv58ikohAarQ7OkUlqjsq6JqkNAFKnystTUePSCis6B31wt9YgGvlM1aRotDp0DvpQWmGl9DQrwEgFAABRs7jiGUuaJDA9BXfbCUS/LFO6QLrmgekp3DxnQ3x9jdKRLgDw68lShVDq/8HPAETNwlbfBkvtWRSVHsSOndotvu2zuhJBMDCHp4/uY2z0lrAaiQAFhUW4PPAQxfsOUTdli4VXL9Dbbsen90EGRM2ia/RZzpoLLPhn0F1/hMB2ujXnzQGguMwM26kWAou9gSrMTvjAOzkshRcpfbvoDUZwLh7lVTWiZrE3MOBnYiBqVhQd1aaMNxfQG4zoGw+J4/hajFDNAWStOZA8N2HzU+5OuUQ+QHlVDTgXDwDgnRxmJ3wSB41CP4Oh+U1KaTpA74594yHoDUYAiSV0VJuouhQ5v6Sf/AoIk0k/p0OhXz5AlpEPsBReFJ9k+eM7STUZhX75AHevXQTn4vFtYwP3ulqk5SQU+uVfwkyj+CXMMv8DEMTX16jfA73BmLRnZ4rde/ZS49WVCMGb+ecoMR8VxQs37oB3cr/zFVJEQWERznffprRgYI7B8cZLaLzaRxVyxXCPgwFh8xNHsjKztJ5V3vpncb3+8B86lPpn0NtWmziUChA1i2Nn2mE92QhTyX7ka3ZtuWX7xKJfEXr9ElMPhvHYO5DqT8q/yXdT6gC1Lkc+ZAAAAABJRU5ErkJggg==
// ==/UserScript==
(function() {
'use strict';
window.areufind = 2333;
window.areuskip = false;
window.color_red = "color: #a5361c";
window.color_blue = "color: #0f5290";
window.color_lightblue = "color: #2c87b2";
//这是延时
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
//时间戳转换
function timestamp(itemtime,now){
if(itemtime.indexOf("刚刚") != -1){
itemtime = now.valueOf()
}
else if(itemtime.indexOf("秒") != -1){
itemtime = now.valueOf() - (itemtime.substring(0,itemtime.indexOf("秒")) * 1000);
}
else if(itemtime.indexOf("分钟") != -1){
itemtime = now.valueOf() - (itemtime.substring(0,itemtime.indexOf("分钟")) * 60 * 1000);
}
else if(itemtime.indexOf("小时") != -1){
itemtime = now.valueOf() - (itemtime.substring(0,itemtime.indexOf("小时")) * 60 * 60 * 1000);
}
else if(itemtime.indexOf("天") != -1){
if(itemtime.indexOf("昨天") != -1){
itemtime = now.valueOf() - now.getHours() * 60 * 60 * 1000;
}
else if(itemtime.indexOf("前天") != -1){
itemtime = now.valueOf() - (now.getHours() * 60 * 60 * 1000) + 86400000;
}
else{
itemtime = now.valueOf() - (now.getHours() * 60 * 60 * 1000) + itemtime.substring(0,itemtime.indexOf("天")) * 86400000;
}
}
else{
itemtime = itemtime.replace(/\//g, "-");
itemtime = itemtime.replace(/年/g, "-");
itemtime = itemtime.replace(/月/g, "-");
//itemtime = itemtime.replace(/日/g, "");
if(itemtime.indexOf("日") != -1){
itemtime = itemtime.substring(0,itemtime.indexOf("日"))
}
if((itemtime.split("-").length - 1) == 1){
itemtime = now.getFullYear() + "-" +itemtime;
}
let temptime = new Date(itemtime);
itemtime = temptime.valueOf();
}
return itemtime;
}
//找出荧幕目前所在的动态
function finditem(item_num,two,now = null){
try{
let items = document.querySelector('.bili-dyn-list__items');
let item = items.querySelectorAll('.bili-dyn-list__item');
for(let btn of item){
item_num = item_num + 1;
//console.log(item_num + ": " +btn.getBoundingClientRect().top);
if(btn.getBoundingClientRect().top > 0){
if(item_num >= 1){
item_num = item_num - 1;
}
//let itemtime = btn.querySelector('.bili-rich-text__content');
//itemtime = itemtime.innerText;
//console.log("> " + itemtime + " <");
break;
}
}
if(two == 2){
console.log("%c从 " + (item_num + 1) + " 项开始遍历",window.color_blue);
}
else{
console.log("%c截止到 " + (item_num + 1) + " 项结束",window.color_blue);
//转化时间戳
item = items.children[item_num];
//item.scrollIntoView();
//window.scrollTo(0, window.scrollY - 70);
let itemtime = item.querySelector('.bili-dyn-time');
itemtime = itemtime.innerText;
item_num = timestamp(itemtime,now);
}
//window.areufind = true;
return item_num;
}
catch (err){
console.log("%c###### 先别急, 页面尚未加载完 ######",window.color_red);
//console.log(err);
window.areufind = true;
return null;
}
}
//实际运行的地方
async function run(time,now,two = false,ddd){
let item_num = -1;
let item_number = 0;
//妈的,再嵌套一个函数 - 遍历动态主函数
async function checkitem(item,item_num){
//如果存在
item.scrollIntoView();
window.scrollTo(0, window.scrollY - 70);
item_number = item_number + 1;
//等待图片加载
let itemimg = item.querySelectorAll('picture.b-img__inner');
if(itemimg != undefined){
for(let num of itemimg){
//console.log("1 " + itemimg);
let img1 = num.lastChild;
//console.log("2 " + itemimg);
let areuokimg = -1;
if(img1.src.indexOf("none") != -1){
console.log("# 跳过: " + img1.src);
continue;
}
else{
//img1.onerror = function() { areuokimg = false; };
}
while(img1.naturalWidth === 0 && window.areuskip != true){
//忘记在这里写强制暂停了
if(window.areufind == true){
return;
}
if(img1.complete == true){
console.log("%c# 图片加载失败: " + img1.src ,window.color_red);
//areuokimg = -1;
img1.src = img1.src;
}
else{
console.log("# 等待图片加载: " + img1.src);
}
await delay(1000);
}
if(window.areuskip == true){
window.areuskip = false;
console.log("# 跳过: " + img1.src);
continue;
}
}
}
item_num = item_num + 1;
return item_num;
}
async function checknewitem(two){
//检查是否到达世界的尽头
let no_more = document.querySelector('.bili-dyn-list-no-more');
let itemss = document.querySelector('.bili-dyn-list__items');
//console.log(no_more);
//console.log(itemss.length);
if (no_more != undefined && itemss.length == undefined && two != 2) {
console.log("%c# 你已经到达世界的尽头 #",window.color_red);
console.log("%c完成!!!",window.color_blue);
window.areufind = true;
}
else if (no_more != undefined && two == 2) {
console.log("%c# 你已经到达世界的尽头 #",window.color_red);
console.log("%c完成!!!",window.color_blue);
window.areufind = true;
}
else if(window.areufind != true){
//console.log("# 错误: \n" + err);
console.log("%c# 遇到了一些错误, 尝试重试 #",window.color_red);
await delay(1000);
window.scrollTo(0, 0);
window.scrollTo(0, document.documentElement.scrollHeight);
}
}
//首先判断当前DOM所在位置
if(two == 2){
item_num = finditem(item_num,two);
if(item_num == null){
return;
}
}
//主循环
while(window.areufind != true){
try{
let items = document.querySelector('.bili-dyn-list__items');
let item;
if(two == true){
item = items.firstChild;
}
else if(two == false){
item = items.children[1];
}
//遍历操作在这里
else if(two == 2){
item = items.children[item_num];
//console.log(item);
if(item == undefined && window.areufind != true){
while(item == undefined){
console.log("%c# 遇到了一些错误, 尝试重试 #",window.color_red);
window.scrollTo(0, 0);
window.scrollTo(0, document.documentElement.scrollHeight);
//window.scrollTo(0, document.documentElement.offsetHeight);
//检查是否到底
let no_more = document.querySelector(".bili-dyn-list-no-more");
if(no_more != undefined) {
window.areufind = true;
break;
}
else{
await delay(1000);
item = items.children[item_num];
//item_num = checkitem(item,item_num);
}
}
if(item != undefined){
item_num = await checkitem(item,item_num);
}
}
else{
item_num = await checkitem(item,item_num);
}
//window.areufind = true;
//return;
}
let itemtime;
let itemtag;
if(item != undefined){
itemtime = item.querySelector('.bili-dyn-time');
if(itemtime != null){ //正常获取动态上的时间
itemtime = itemtime.innerText;
itemtag = item.querySelector('.bili-dyn-tag__text');
//itemtag = itemtag.innerText;
console.log("> " + itemtime + " <");
//统统转成时间戳
itemtime = timestamp(itemtime,now);
}
else{ //如果遇到 '1条动态被折叠' 的话
itemtime = item.querySelector('.bili-dyn-item-fold__statement.fs-small');
console.log("%c> " + itemtime.innerText + " <",window.color_red);
itemtime = new Date();
itemtime = itemtime.valueOf();
}
console.log(itemtime);
}
if(item != undefined){
if(itemtime > time){
if(two != 2){
item.remove();
item_number = item_number + 1;
}
}
else if(itemtag != undefined){
if(two == true){
item.remove();
item_number = item_number + 1;
}
}
else{
item.scrollIntoView();
window.scrollTo(0, window.scrollY - 70);
console.log("%c完成!!!",window.color_blue);
window.areufind = true;
}
}
else{
await checknewitem(two);
}
}
catch (err){
console.log("%c# 错误: \n" + err.stack ,window.color_red);
await checknewitem(two);
}
//areufind = true;
await delay(ddd);
//时间统计
if(window.areufind == true){
let nowtime = new Date();
let spendtime = nowtime.valueOf() - now.valueOf();
let hhh
let mmm
let sss
if(spendtime >= 3600000){
hhh = spendtime / 1000 / 60 / 60;
}
else{
hhh = 0;
}
if(spendtime >= 60000){
mmm = (spendtime - Math.trunc(hhh) * 3600000) / 1000 / 60;
}
else{
mmm = 0;
}
sss = (spendtime - Math.trunc(hhh) * 3600000 - Math.trunc(mmm) * 60000) / 1000;
console.log("%c###### 总计用时: " + Math.trunc(hhh) + "小时" + Math.trunc(mmm) + "分钟" + Math.trunc(sss) + "秒, 总计 " + item_number + " 项动态 ######",window.color_blue);
}
}
};
//接受参数
window.bilidel = function(input,ddd = 1,two = false) {
//console.log(window.areufind);
let returns = "################################";
//帮助
if(input == "Help" || input == "help"){
//console.log("帮助\n");
//好麻烦
let text = "%c#############################################################################################################\n";
text = text + "#\t\t\t\t\t\t\t\t\t\t\t\t 介素幫助 \t\t\t\t\t\t\t\t\t\t\t\t#\n";
text = text + "#############################################################################################################\n";
text = text + "# bbdel\(\"指定日期\"\,\"停頓時間, 單位ms\"\,\"操縱類型\"\)\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#\n";
text = text + "# bbdel\(\"list\"\)\t\t\t\t\t查詢當前動態的總數目\;\t\t\t\t\t\t\t\t\t\t\t\t\t\t#\n";
text = text + "# bbdel\(\"stop\"\)\t\t\t\t\t終止任務運行\;\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#\n";
text = text + "# bbdel\(\"skip\"\)\t\t\t\t\t跳過失效圖像部分\;\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#\n";
text = text + "# bbdel\(\"help\"\)\t\t\t\t\t獲取幫助。\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#\n";
text = text + "#===========================================================================================================#\n";
text = text + "# 舉個栗子\:\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#\n";
text = text + "# bbdel\(\"2024-12-5\"\,\"1000\"\,\"2\"\)\t導航到 2024-12-5 的動態, 延時1000ms\;\t\t\t\t\t\t\t\t\t\t#\n";
text = text + "# bbdel\(\"2024-12-5\"\)\t\t\t保留置頂, 清除至 2024-11-16 之間的動態 \(並不是真的把動態刪掉\)\;\t\t\t\t#\n";
text = text + "# bbdel\(\"1733392922\"\,\"100\"\,\"1\"\)\t不保留置頂, 延時100ms, 清除至 2024-12-5 之間的動態 \(並不是真的把動態刪掉\)\。\t#\n";
text = text + "#############################################################################################################";
console.log(text,window.color_lightblue);
return undefined;
}
if(window.areufind == false){
if(input == "stop" || input == "Stop"){
window.areufind = true;
console.log("%c# 终止任务 #",window.color_red);
}
else if(input == "skip" || input == "Skip"){
window.areuskip = true;
console.log("%c# 尝试跳过 #",window.color_red);
}
else{
console.log("%c\(#`O′\) 上一次任务尚未完成欸!!!",window.color_red);
}
return "################################";
}
if(input == "stop" || input == "Stop" || input == "skip" || input == "Skip"){
console.log("%c\(#`O′\) 参数错误欸。",window.color_red);
console.log("%c键入 bbdel\(\"help\"\) 以尋求幫助。",window.color_blue);
}
else if(input == "List" || input == "list"){
bblist();
return undefined;
}
else{
//console.log(input);
let now = new Date();
let Y;
let M;
let D;
//给了目标日期
if(input == "" || input == undefined || input == null){
if(two == 2){
input = "1970-1-1";
}
}
if(input != "" && input != undefined && input != null){
input = input.replace(/\//g, "-");
input = input.replace(/年/g, "-");
input = input.replace(/月/g, "-");
input = input.replace(/日/g, "");
if((input.split("-").length - 1) == 0){
if(input == "0"){
input = "1970-1-1";
}
else if(input.length > 4){
input = new Date(input * 1);
console.log(input);
input = input.getFullYear() + "-" + (input.getMonth() + 1) + "-" + input.getDate();
}
else if(input.length > 2){
input = input + "-1-1";
}
else{
input = now.getFullYear() + "-1-" + input;
}
}
Y = input.substring(0,input.indexOf("-"));
M = input.substring(input.indexOf("-") + 1);
if(M.indexOf("-") != -1){
M = M.substring(0,M.indexOf("-"));
}
if((input.split("-").length - 1) > 1){
D = input.substring((Y + "-" + M + "-").length);
}
else{
D = 1;
}
if((input.split("-").length - 1) > 2){
console.log("%c\(#`O′\) 你参数写错了欸。",window.color_red);
console.log("%c键入 bbdel\(\"help\"\) 以尋求幫助。",window.color_blue);
return "################################";
}
else if((input.split("-").length - 1) == 1){
if(Y.length > 2){
D = 1;
}
else{
D = M;
M = Y;
Y = now.getFullYear();
}
}
}
//没给具体日期
else{
let item_time = finditem(-1,two,now);
item_time = new Date(item_time + 86400000);
Y = item_time.getFullYear();
M = item_time.getMonth() + 1;
D = item_time.getDate();
}
console.log("年: " + Y);
console.log("月: " + M);
console.log("日: " + D);
let time = new Date(Y + "-" + M + "-" + D);
time = time.valueOf();
console.log("当前时间戳: " + now.valueOf());
console.log("目标时间戳: " + time);
//要不要把置顶给干了
if(two == 2){
//two = 2;
console.log("准备开始遍历动态");
}
else{
if(two == 1 && Number.isNaN(time) != true){
two = true;
}
else if(two == 0 && Number.isNaN(time) != true){
two = false;
}
else{
console.log("%c\(#`O′\) 你参数写错了欸。",window.color_red);
console.log("%c键入 bbdel\(\"help\"\) 以尋求幫助。",window.color_blue);
return "################################";
}
console.log("是否把置顶给干了: " + two);
//防误操作,先询问
let areudel = prompt("需要删除 " + Y + "-" + M + "-" + D + " 之前的动态吗? (Y/N)", "N");
if(areudel == "Y" || areudel == "y" || areudel == "yes" || areudel == "Yes" || areudel == 1 || areudel == true){
console.log("%c出发喽~~~",window.color_blue);
}
else{
console.log("%c# 任务取消 #",window.color_red);
return "################################";
}
}
window.areufind = false;
run(time,now,two,ddd);
if(window.areufind == false){
returns = undefined;
}
}
return returns;
};
window.Bilidel = window.bilidel
window.bbdel = window.bilidel
window.BBdel = window.bilidel
//计数
let bblist = function(){
try{
let items = document.querySelector('.bili-dyn-list__items');
let item = items.querySelectorAll('.bili-dyn-list__item');
let no_more = document.querySelector('.bili-dyn-list-no-more');
if(item != undefined || item != null){
let tip;
if(no_more == undefined || no_more == null)
{
tip = ", 尚未全部加载完成欸。"
}
else{
tip = ", 已全部加载完成。"
}
console.log("%c###### 总计 " + item.length + " 项动态" + tip + " ######",window.color_blue);
}
else{
console.log("%c# 找不到任何动态欸 #",window.color_red);
}
}
catch{
console.log("%c# 找不到任何动态欸 #",window.color_red);
}
return undefined;
}
})();