炸号微博备份

炸号微博一键备份

目前为 2022-05-18 提交的版本。查看 最新版本

// ==UserScript==
// @name         炸号微博备份
// @namespace    https://dun.mianbaoduo.com/@fun
// @version      0.5
// @description  炸号微博一键备份
// @author       fun
// @match        *://weibo.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=weibo.com
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
  "use strict";

  let wrapper = document.createElement("div");
  let btn = document.createElement("button");
  let backup = document.createElement("div");

  backup.innerHTML = `<div><svg id="bIndicator" style="vertical-align: -12px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" class="woo-spinner-main Scroll_loadingIcon_2nyZ4"><g fill="none" stroke-width="5" stroke-miterlimit="10" stroke="currentColor" style="animation: 2s linear 0s infinite normal none running woo-spinner-_-rotate; height: 50px; transform-origin: center center; width: 50px;"><circle cx="25" cy="25" r="20" opacity=".3"></circle><circle cx="25" cy="25" r="20" stroke-dasharray="25,200" stroke-linecap="round" style="animation: 1.5s ease-in-out 0s infinite normal none running woo-spinner-_-dash;"></circle></g></svg><span id="bMSG"></span></div>

<div style="text-align: center;"><a href="https://dun.mianbaoduo.com/@fun" target="_blank" style="border-radius: 0.166667rem; display: inline-block; font-weight: bold; color: #ca3a1f; margin-left: 0px; padding: 3px 14px;font-size: 13px;text-align: center;border: 1px solid #cfcfcf;margin-top: 8px;">打赏<span style="font-size: 16px; vertical-align: -2px; margin-left: 5px;">😋</span></a></div>  `;

  function download(content, fileName, contentType) {
    var a = document.createElement("a");
    var file = new Blob([content], { type: contentType });
    a.href = URL.createObjectURL(file);
    a.download = fileName;
    a.click();
  }
  //   download(jsonData, "json.txt", "text/plain");
  async function fetchContent(uid = 0, page = 1, since_id = null) {
    const req = await fetch(
      `https://weibo.com/ajax/statuses/mymblog?uid=${uid}&page=${page}&feature=0&` +
        (since_id ? "since_id=" + since_id : ""),
      {
        headers: {
          accept: "application/json, text/plain, */*",
          "accept-language": "zh-CN,zh;q=0.9,en-IN;q=0.8,en;q=0.7,ar;q=0.6",
          "sec-ch-ua":
            '" Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"',
          "sec-ch-ua-mobile": "?0",
          "sec-ch-ua-platform": '"macOS"',
          "sec-fetch-dest": "empty",
          "sec-fetch-mode": "cors",
          "sec-fetch-site": "same-origin",
          "x-requested-with": "XMLHttpRequest",
        },
        referrer: `https://weibo.com/u/${uid}`,
        referrerPolicy: "strict-origin-when-cross-origin",
        body: null,
        method: "GET",
        mode: "cors",
        credentials: "include",
      }
    );
    const data = await req.json();
    return data;
  }

  async function fetchAll() {
    var uid = $CONFIG.uid;
    let page = 1;
    let allPageData = [];
    let noMore = false;
    for (let index = 0; index < Infinity; index++) {
      console.log("scan", "page", page);
      printLog(`正在备份第 ${page} 页`);
      for (let index = 0; index < 10; index++) {
        const pageData = await fetchContent(uid, page);
        if (pageData.ok) {
          allPageData.push(pageData);
          if (pageData.data.list.length === 0) noMore = true;
          break;
        }
        await new Promise((resolve) => {
          setTimeout(resolve, 3000);
        });
        console.log("retry", index);
        printLog(`[重试]备份第 ${page} 页`);
      }
      page++;
      if (noMore) break;
      await new Promise((resolve) => {
        setTimeout(resolve, 3000);
      });
    }
    console.log("all done");
    printLog(`备份完毕! 打开【下载内容】查看数据文件`);
    const parsed = allPageData.reduce((all, item) => {
      item.data.list.forEach((c) => {
        const formatted = {
          images: c.pic_ids.map((d) => {
            return c.pic_infos[d].large.url;
          }),
          text: c.text,
          created_at: c.created_at,
            raw: c,
        };
        if (c.retweeted_status) {
          formatted.retweeted_status = {
            text: c.retweeted_status.text,
            images:
              c.retweeted_status.pic_ids &&
              c.retweeted_status.pic_ids.map((d) => {
                return c.retweeted_status.pic_infos[d].large.url;
              }),
          };
        }
        all.push(formatted);
      });
      return all;
    }, []);
    console.log("data", allPageData, parsed);
    download(
      JSON.stringify(parsed, null, 2),
      "weibo-" + Date.now() + ".json",
      "text/plain"
    );
  }

  function printLog(msg) {
    tip.innerText = msg;
  }

  btn.innerHTML = "备份我的微博";

  backup.setAttribute(
    "style",
    "display:none; background: white; color: black; font-size: 13px; padding: 10px 10px 15px 10px;"
  );

  btn.setAttribute(
    "style",
    `border-radius: 0.166667rem; display: inline-block; font-weight: bold; color: #444; margin:0 auto; padding: 5px 14px;font-size: 13px;text-align: center;border: 1px solid #cfcfcf;margin-top: 3px; cursor: pointer;`
  );

  //   backup.appendChild(tip);
  wrapper.appendChild(backup);
  wrapper.appendChild(btn);
  document.body.appendChild(wrapper);
  wrapper.setAttribute(
    "style",
    `position: fixed;
    border-radius: 3px;
    background: white;
    top: 80px;
    right: 20px;
    z-index: 100000;
    padding:10px 15px;
text-align: center; 
   `
  );

  let started = false;

  let tip = document.getElementById("bMSG");
  let indicator = document.getElementById("bIndicator");
  btn.addEventListener("click", async () => {
    if (started) {
      alert("started");
      return;
    }
    started = true;
    btn.style.display = "none";
    backup.style.display = "block";
    indicator.style.display = "inline-block";
    await fetchAll();
    started = false;
    btn.style.display = "block";
    indicator.style.display = "none";
  });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址