Greasy Fork

Greasy Fork is available in English.

JS 下载云听电台往期音频

一键下载当前页面所有录音文件,显示下载失败的文件,显示整个网页的爬取状况

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         JS 下载云听电台往期音频
// @namespace    https://www.radio.cn/
// @version      1.71
// @description  一键下载当前页面所有录音文件,显示下载失败的文件,显示整个网页的爬取状况
// @match        https://www.radio.cn/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    function formatDate(dateStr) {
        const date = new Date(dateStr);
        const year = date.getFullYear();
        const month = date.getMonth() + 1;
        const day = date.getDate();
        return year + '-' + (month < 10 ? '0' : '') + month + '-' + (day < 10 ? '0' : '') + day;
    }

    function downloadAll() {
        const downloadLinks = [];
        for (const a of document.getElementsByTagName('a')) {
            if (!a.hasAttribute('onclick')) continue;
            const onclick = a.getAttribute('onclick');
            const matches = onclick.match(/downLiveRecord\(['"](.*?)['"]/);
            if (matches) {
                let href = matches[1].replace(/\[|\]|"/g, '');
                const dateMatch = href.match(/\/(\d{4})(\d{2})(\d{2})\//);
                if (dateMatch) {
                    const dateStr = dateMatch[1] + '-' + dateMatch[2] + '-' + dateMatch[3];
                    const fileName = formatDate(dateStr) + '.mp3';
                    if (href.startsWith('https://')) {
                        downloadLinks.push({href: href, fileName: fileName});
                    } else {
                        href = 'https://' + href.replace(/^http:\/\//i, '');
                        downloadLinks.push({href: href, fileName: fileName});
                    }
                }
            }
        }

        downloadLinks.sort(function(a, b){
            return a.fileName.localeCompare(b.fileName);
        });

        const progressEl = document.createElement('div');
        progressEl.style.position = 'fixed';
        progressEl.style.bottom = '100px';
        progressEl.style.right = '50px';
        progressEl.style.padding = '10px 20px';
        progressEl.style.fontSize = '16px';
        progressEl.style.borderRadius = '5px';
        progressEl.style.color = '#fff';
        progressEl.style.backgroundColor = '#f00';
        progressEl.style.cursor = 'default';
        document.body.appendChild(progressEl);

        const currentProgressEl = document.createElement('div');
        currentProgressEl.style.position = 'fixed';
        currentProgressEl.style.bottom = '160px';
        currentProgressEl.style.right = '50px';
        currentProgressEl.style.width = '200px';
        currentProgressEl.style.padding = '10px 20px';
        currentProgressEl.style.fontSize = '16px';
        currentProgressEl.style.borderRadius = '5px';
        currentProgressEl.style.color = '#fff';
        currentProgressEl.style.backgroundColor = '#009688';
        currentProgressEl.style.cursor = 'default';
        currentProgressEl.style.display = 'none';
        document.body.appendChild(currentProgressEl);


        let downloadCount = 0;
// 创建新的绿色按钮元素
const greenButton = document.createElement('button');
greenButton.textContent = '下载失败的文件';
greenButton.style.position = 'fixed';
greenButton.style.bottom = '150px';
greenButton.style.right = '50px';
greenButton.style.padding = '10px 20px';
greenButton.style.fontSize = '16px';
greenButton.style.borderRadius = '5px';
greenButton.style.color = '#fff';
greenButton.style.backgroundColor = 'green';
greenButton.style.cursor = 'pointer';

// 将绿色按钮添加到页面中
document.body.appendChild(greenButton);

// 为新按钮添加点击事件处理函数
greenButton.addEventListener('click', function() {
  const errors = downloadLinks.filter(function(link) {
    return !link.success;
  }).map(function(link) {
    return link.fileName;
  });

  if (errors.length > 0) {
    alert('以下文件下载失败:\n\n' + errors.join('\n'));
  } else {
    alert('没有文件下载失败!');
  }
});



function downloadNext() {
  if (downloadCount >= downloadLinks.length) {
    progressEl.textContent = '爬取进度:' + downloadCount + '/' + downloadLinks.length + ',全部完成';
    currentProgressEl.style.display = 'none';
    return;
  }

  const link = downloadLinks[downloadCount];
  const xhr = new XMLHttpRequest();
  xhr.open('GET', link.href);
  xhr.responseType = 'blob';
  xhr.onload = function() {
    if (xhr.status === 200) {
      downloadCount++;
      const blob = new Blob([xhr.response], { type: 'audio/mp3' });
      URL.revokeObjectURL(link.href);
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = link.fileName;
      document.body.appendChild(a);
      a.click();
      a.remove();

      // 下载成功,更新进度
      progressEl.textContent = '爬取进度:' + downloadCount + '/' + downloadLinks.length;
      if (currentProgressEl) {
        currentProgressEl.textContent = '';
        currentProgressEl.style.display = 'none';
      }

      // 标记当前链接下载成功
      link.success = true;

      setTimeout(downloadNext, 500);
    } else {
      // 下载失败,标记当前链接下载失败
      downloadCount++;
      link.success = false;
      setTimeout(downloadNext, 0);
    }
  };

  // 发送请求
  xhr.send();
}


        downloadNext();
    }

    const button = document.createElement('button');
    button.textContent = "下载当前页面所有录音文件";
    button.style.position = 'fixed';
    button.style.bottom = '50px';
    button.style.right = '50px';
    button.style.padding = '10px 20px';
    button.style.fontSize = '16px';
    button.style.borderRadius = '5px';
    button.style.color = '#fff';
    button.style.backgroundColor = '#f00';
    button.style.cursor = 'pointer';
    button.addEventListener('click', function() {
        downloadAll();
    });

    document.body.appendChild(button);

})();