导出即刻收藏
// ==UserScript==
// @name 即刻收藏导出
// @namespace https://xhs.mundane.ink
// @version 1.0
// @description 导出即刻收藏
// @match https://web.okjike.com/me/*
// @match https://web.okjike.com/u/*/collection
// @license MIT
// @run-at document-start
// @grant unsafeWindow
// @require https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.0/xlsx.full.min.js
// @icon https://web.okjike.com/favicon-32x32.png
// ==/UserScript==
(function () {
"use strict";
console.log("即刻脚本生效了");
const collectionList = [];
const btnScroll = document.createElement("button");
btnScroll.innerHTML = "自动滚动";
btnScroll.style.position = "fixed";
btnScroll.style.top = "160px";
btnScroll.style.right = "20px";
btnScroll.style.backgroundColor = "#056b00";
btnScroll.style.color = "#fff";
btnScroll.style.padding = "8px";
btnScroll.style.borderRadius = "6px";
btnScroll.style.zIndex = "1000";
const btnCount = document.createElement("button");
btnCount.innerHTML = "捕获数量:" + collectionList.length;
btnCount.style.position = "fixed";
btnCount.style.top = "210px";
btnCount.style.right = "20px";
btnCount.style.backgroundColor = "#056b00";
btnCount.style.color = "#fff";
btnCount.style.padding = "8px";
btnCount.style.borderRadius = "6px";
btnCount.style.zIndex = "1000";
const btnExport = document.createElement("button");
btnExport.innerHTML = "导出收藏";
btnExport.style.position = "fixed";
btnExport.style.top = "260px";
btnExport.style.right = "20px";
btnExport.style.backgroundColor = "#056b00";
btnExport.style.color = "#fff";
btnExport.style.padding = "8px";
btnExport.style.borderRadius = "6px";
btnExport.style.zIndex = "1000";
document.body.appendChild(btnExport);
document.body.appendChild(btnScroll);
document.body.appendChild(btnCount);
let isScrolling = false;
let timerId;
function simulateScroll() {
// window.scrollBy(0, 200);
window.scrollBy({ top: 200, left: 0, behavior: "smooth" });
}
function startScroll() {
if (isScrolling) {
return;
}
isScrolling = true;
btnScroll.innerHTML = "停止滚动";
btnScroll.style.backgroundColor = "#ff2442";
timerId = setInterval(simulateScroll, 200);
}
function cancelScroll() {
if (!isScrolling) {
return;
}
isScrolling = false;
btnScroll.style.backgroundColor = "#056b00";
btnScroll.innerHTML = "自动滚动";
if (timerId) {
clearInterval(timerId);
}
}
// 给按钮添加点击事件
btnScroll.addEventListener("click", function () {
if (isScrolling) {
cancelScroll();
} else {
startScroll();
}
});
btnExport.addEventListener("click", function () {
// 创建工作簿
const wb = XLSX.utils.book_new();
// 准备数据
const data = [
["链接", "内容", "用户", "创建时间"],
...collectionList.map((item) => [
item.url,
item.content,
item.user,
item.createdAt,
]),
];
// 创建工作表
const ws = XLSX.utils.aoa_to_sheet(data);
// 将工作表添加到工作簿
XLSX.utils.book_append_sheet(wb, ws, "即刻收藏");
// 生成 Excel 文件并下载
XLSX.writeFile(wb, "即刻收藏.xlsx");
});
// 拦截 fetch 请求
const originFetch = fetch;
window.unsafeWindow.fetch = (url, options) => {
return originFetch(url, options).then(async (response) => {
if (url === "https://web-api.okjike.com/api/graphql") {
const responseClone = response.clone();
let res = await responseClone.json();
intercept(res);
const responseNew = new Response(JSON.stringify(res), response);
return responseNew;
} else {
return response;
}
});
};
function formatDate(dateString) {
// 创建 Date 对象
const date = new Date(dateString);
// 获取年、月、日、时、分、秒
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
// 组合成所需格式
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
function intercept(res) {
if (
res.data &&
res.data.viewer &&
res.data.viewer.collections &&
res.data.viewer.collections.nodes
) {
const nodes = res.data.viewer.collections.nodes;
const collections = nodes.map((node) => {
return {
url: `https://web.okjike.com/originalPost/${node.id}`,
content: node.content,
user: node.user.screenName,
createdAt: formatDate(node.createdAt),
};
});
collectionList.push(...collections);
btnCount.innerHTML = "捕获数量:" + collectionList.length;
}
}
})();