LINUX SB 快照站

LINUX SB 文章图片一键下载精华

原帖: linux.sb/topic/11653 · 共 5 楼 · 标题快照 2026-08-12 11:18:50

楼主
发帖 2026-08-12 11:12:52 · 快照 2026-08-12 11:18:50

测试帖子
https://linux.sb/topic/11607

// ==UserScript==
// @name         LINUX SB文章图片下载
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  LINUX SB 文章图片一键下载
// @author       吴老狗
// @match        https://linux.sb/*
// @run-at       document-idle
// @grant        GM_xmlhttpRequest
// @connect      *
// ==/UserScript==
(function () {
  'use strict';

  // 下载间隔(毫秒),避免浏览器因短时间内多次触发下载而拦截
  const DOWNLOAD_INTERVAL = 400;

  function createButton() {
     const userCard = document.querySelector('.user-card');

    const a = document.createElement('a');
    a.textContent = '下载文章所有图片';
    a.className = 'btn-post';

    a.addEventListener('click', () => handleClick(a));

    userCard.appendChild(a);
  }

  // 获取图片列表:优先用 cgiDataNew,拿不到就退化为扫描正文里的 <img>
  function getImageList() {
   const imgs = [...document.querySelectorAll('.post-content img')].map(img => img.src);

    return { urls: [...new Set(imgs)], prefix: 'sb_img' };
  }

  // 根据响应的 Content-Type 推断扩展名,拿不到就退回原 url 里的后缀,最后兜底 jpg
  function guessExt(blob, url) {
    const map = {
      'image/jpeg': 'jpg',
      'image/png': 'png',
      'image/gif': 'gif',
      'image/webp': 'webp',
      'image/bmp': 'bmp'
    };
    if (blob.type && map[blob.type]) return map[blob.type];
    const m = url.match(/\.(jpe?g|png|gif|webp|bmp)(\?|$)/i);
    if (m) return m[1].toLowerCase().replace('jpeg', 'jpg');
    return 'jpg';
  }

  async function downloadImage(url, filename) {
    return new Promise((resolve, reject) => {
      GM_xmlhttpRequest({
        method: 'GET',
        url,
        responseType: 'blob',
        headers: {
          Referer: ''
        },
        onload(res) {
          if (res.status < 200 || res.status >= 300) {
            reject(new Error(`HTTP ${res.status}`));
            return;
          }

          const blobUrl = URL.createObjectURL(res.response);

          const a = document.createElement('a');
          a.href = blobUrl;
          a.download = filename;

          document.body.appendChild(a);
          a.click();
          a.remove();

          setTimeout(() => {
            URL.revokeObjectURL(blobUrl);
          }, 2000);

          resolve();
        },
        onerror: reject
      });
    });
  }
  // async function downloadImage(urll, filenameBase) {
  //   const url = urll.replace('http://', 'https://');
  //
  //   const res = await fetch(url, {
  //     referrerPolicy: 'no-referrer'
  //   });
  //   if (!res.ok) throw new Error(`HTTP ${res.status}`);
  //   const blob = await res.blob();
  //   const ext = guessExt(blob, url);
  //   const blobUrl = URL.createObjectURL(blob);
  //   const a = document.createElement('a');
  //   a.href = blobUrl;
  //   a.download = `${filenameBase}.${ext}`;
  //   document.body.appendChild(a);
  //   a.click();
  //   a.remove();
  //   setTimeout(() => URL.revokeObjectURL(blobUrl), 2000);
  // }

  function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  async function handleClick(btn) {
    const { urls, prefix } = getImageList();

    if (!urls.length) {
      alert('未找到可下载的图片');
      return;
    }

    btn.disabled = true;
    const originalText = btn.textContent;
    let success = 0;
    let fail = 0;

    for (let i = 0; i < urls.length; i++) {
      btn.textContent = `下载中 ${i + 1}/${urls.length}`;
      try {
        await downloadImage(urls[i], `${prefix}_${i + 1}`);
        success++;
      } catch (err) {
        fail++;
        console.error('图片下载失败:', urls[i], err);
      }
      // 最后一张不用再等
      if (i < urls.length - 1) await sleep(DOWNLOAD_INTERVAL);
    }

    btn.disabled = false;
    btn.textContent = originalText;
    alert(`下载完成:成功 ${success} 张,失败 ${fail} 张`);
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', createButton);
  } else {
    createButton();
  }
})();
#1
发帖 2026-08-12 11:17:51 · 快照 2026-08-12 11:18:50

建议搞插件,丰富sb站插件生态

#2
发帖 2026-08-12 11:19:18 · 快照 2026-08-12 11:21:35

@SpongeBob #1 我研究一下插件,看看怎么弄