最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

11個(gè)JavaScript實(shí)用自動(dòng)化腳本(文件管理,通知提醒,數(shù)據(jù)抓取)

 更新時(shí)間:2025年08月29日 09:54:47   作者:walking957  
在日常工作與學(xué)習(xí)中,我們常常會(huì)被文件備份、郵件發(fā)送、格式轉(zhuǎn)換等重復(fù)性任務(wù)占用大量時(shí)間,本文和大家分享了11個(gè)經(jīng)過(guò)實(shí)踐驗(yàn)證的JavaScript實(shí)用腳本,大家可以根據(jù)需要進(jìn)行選擇

在日常工作與學(xué)習(xí)中,我們常常會(huì)被文件備份、郵件發(fā)送、格式轉(zhuǎn)換等重復(fù)性任務(wù)占用大量時(shí)間。而JavaScript(尤其是基于Node.js的腳本)憑借其強(qiáng)大的生態(tài)與便捷的文件、網(wǎng)絡(luò)操作能力,能成為自動(dòng)化這些任務(wù)的高效工具。本文將分享11個(gè)經(jīng)過(guò)實(shí)踐驗(yàn)證的JavaScript實(shí)用腳本,涵蓋文件管理、通知提醒、數(shù)據(jù)抓取等多個(gè)場(chǎng)景,每個(gè)腳本均附帶完整代碼、使用說(shuō)明及優(yōu)化建議,幫你徹底解放雙手,聚焦更核心的工作。

1. 自動(dòng)文件備份腳本:再也不怕重要文件丟失

無(wú)論是工作文檔、項(xiàng)目代碼還是個(gè)人照片,重要文件的丟失都可能帶來(lái)巨大的麻煩。這個(gè)腳本能將指定源目錄的所有文件批量復(fù)制到備份目錄,確保你始終擁有文件的最新版本。結(jié)合定時(shí)任務(wù)(如Linux的cron或Windows的任務(wù)計(jì)劃),還能實(shí)現(xiàn)“無(wú)人值守”的自動(dòng)備份。

核心代碼

// 引入Node.js內(nèi)置的文件系統(tǒng)與路徑處理模塊
const fs = require('fs');
const path = require('path');

/**
 * 自動(dòng)備份文件函數(shù)
 * @param {string} sourceFolder - 源文件目錄路徑(需替換為實(shí)際路徑)
 * @param {string} backupFolder - 備份目錄路徑(需替換為實(shí)際路徑)
 */
function backupFiles(sourceFolder, backupFolder) {
  // 讀取源目錄下的所有文件/文件夾
  fs.readdir(sourceFolder, (err, files) => {
    // 若讀取目錄時(shí)出錯(cuò)(如路徑不存在),直接拋出錯(cuò)誤
    if (err) throw new Error(`讀取源目錄失?。?{err.message}`);
    
    // 遍歷每個(gè)文件,執(zhí)行復(fù)制操作
    files.forEach((file) => {
      // 拼接完整的源文件路徑與備份路徑
      const sourcePath = path.join(sourceFolder, file);
      const backupPath = path.join(backupFolder, file);
      
      // 復(fù)制文件(覆蓋已存在的備份文件)
      fs.copyFile(sourcePath, backupPath, (err) => {
        if (err) {
          console.error(`備份文件 ${file} 失?。?{err.message}`);
        } else {
          console.log(`? 成功備份:${file}`);
        }
      });
    });
  });
}

// 配置源目錄與備份目錄(請(qǐng)根據(jù)你的實(shí)際需求修改這兩個(gè)路徑)
const sourceDir = '/Users/your-name/Documents/重要工作文檔'; // 示例:Mac下的工作文檔目錄
const backupDir = '/Volumes/移動(dòng)硬盤(pán)/工作文檔備份'; // 示例:移動(dòng)硬盤(pán)的備份目錄

// 執(zhí)行備份操作
backupFiles(sourceDir, backupDir);

使用說(shuō)明與優(yōu)化建議

前置準(zhǔn)備:無(wú)需額外安裝依賴(lài)(基于Node.js內(nèi)置模塊),直接創(chuàng)建.js文件(如file-backup.js),粘貼代碼并修改sourceDirbackupDir為實(shí)際路徑。

運(yùn)行方式:在終端執(zhí)行node file-backup.js即可手動(dòng)觸發(fā)備份。

定時(shí)備份配置

  • Linux/Mac用戶(hù):通過(guò)crontab -e添加定時(shí)任務(wù),例如0 2 * * * node /path/to/file-backup.js(每天凌晨2點(diǎn)自動(dòng)備份)。
  • Windows用戶(hù):通過(guò)“控制面板→管理工具→任務(wù)計(jì)劃程序”,新建任務(wù)并設(shè)置觸發(fā)時(shí)間與執(zhí)行命令(node.exe C:\path\to\file-backup.js)。

注意事項(xiàng):若備份目錄不存在,腳本會(huì)報(bào)錯(cuò),建議在函數(shù)開(kāi)頭添加fs.existsSync(backupFolder) || fs.mkdirSync(backupFolder, { recursive: true })(自動(dòng)創(chuàng)建不存在的備份目錄)。

2. 預(yù)定電子郵件腳本:精準(zhǔn)定時(shí)發(fā)送,告別“忘記發(fā)送”

工作中常需要在特定時(shí)間發(fā)送郵件(如凌晨的報(bào)表、會(huì)議前的提醒),但手動(dòng)等待發(fā)送既低效又容易遺忘。這個(gè)腳本基于nodemailer庫(kù),支持設(shè)置任意未來(lái)時(shí)間,自動(dòng)觸發(fā)郵件發(fā)送,且通過(guò)環(huán)境變量存儲(chǔ)敏感信息(如郵箱密碼),避免安全風(fēng)險(xiǎn)。

核心代碼

// 引入郵件發(fā)送庫(kù)nodemailer(需提前安裝:npm install nodemailer)
const nodemailer = require('nodemailer');
// 引入dotenv庫(kù)(可選,用于加載環(huán)境變量,避免硬編碼敏感信息)
require('dotenv').config();

/**
 * 預(yù)定電子郵件發(fā)送函數(shù)
 * @param {string} toEmail - 收件人郵箱地址(如:"user@example.com")
 * @param {string} subject - 郵件主題
 * @param {string} body - 郵件正文(支持純文本或HTML格式)
 * @param {number} sendTime - 發(fā)送時(shí)間的時(shí)間戳(毫秒級(jí),如:Date.now() + 60000 表示1分鐘后發(fā)送)
 */
function sendScheduledEmail(toEmail, subject, body, sendTime) {
  // 計(jì)算當(dāng)前時(shí)間到發(fā)送時(shí)間的延遲(毫秒)
  const delay = sendTime - Date.now();
  
  // 若延遲為負(fù)(即發(fā)送時(shí)間已過(guò)),提示錯(cuò)誤并終止
  if (delay < 0) {
    console.error('? 錯(cuò)誤:預(yù)定的發(fā)送時(shí)間已過(guò)期,請(qǐng)?jiān)O(shè)置未來(lái)的時(shí)間');
    return;
  }

  // 延遲指定時(shí)間后執(zhí)行郵件發(fā)送
  setTimeout(() => {
    // 配置郵件發(fā)送器(以Gmail為例,其他郵箱需調(diào)整service或host)
    const transporter = nodemailer.createTransport({
      service: 'gmail', // 郵箱服務(wù)提供商(如:"qq"、"163",或手動(dòng)指定host: "smtp.163.com")
      auth: {
        user: process.env.EMAIL_USER, // 發(fā)件人郵箱(從環(huán)境變量讀取,避免硬編碼)
        pass: process.env.EMAIL_PASS, // 郵箱授權(quán)碼(非登錄密碼,需在郵箱設(shè)置中開(kāi)啟SMTP并獲?。?
      },
    });

    // 配置郵件內(nèi)容
    const mailOptions = {
      from: `"你的名稱(chēng)" <${process.env.EMAIL_USER}>`, // 發(fā)件人信息(格式:"名稱(chēng) <郵箱>")
      to: toEmail, // 收件人郵箱(多個(gè)收件人用逗號(hào)分隔:"a@example.com,b@example.com")
      subject: subject, // 郵件主題
      text: body, // 純文本正文(若需HTML正文,可添加html: "<h1>HTML內(nèi)容</h1>")
    };

    // 發(fā)送郵件
    transporter.sendMail(mailOptions, (error, info) => {
      if (error) {
        console.error(`? 郵件發(fā)送失?。?{error.message}`);
      } else {
        console.log(`? 郵件已成功發(fā)送!響應(yīng)信息:${info.response}`);
      }
    });
  }, delay);
}

// ------------------- 使用示例 -------------------
// 1. 設(shè)置發(fā)送時(shí)間:10秒后發(fā)送(Date.now()獲取當(dāng)前時(shí)間戳,加10000毫秒=10秒)
const scheduledTime = Date.now() + 10000;

// 2. 調(diào)用函數(shù)發(fā)送郵件(替換為你的實(shí)際需求)
sendScheduledEmail(
  'recipient@example.com', // 收件人郵箱
  '項(xiàng)目進(jìn)度提醒', // 郵件主題
  '您好!提醒您本周項(xiàng)目進(jìn)度需在周五前提交,感謝配合!', // 郵件正文
  scheduledTime // 預(yù)定發(fā)送時(shí)間
);

使用說(shuō)明與優(yōu)化建議

前置準(zhǔn)備

執(zhí)行npm init -y初始化項(xiàng)目(生成package.json)。

安裝依賴(lài):npm install nodemailer dotenvdotenv用于管理環(huán)境變量)。

在項(xiàng)目根目錄創(chuàng)建.env文件,寫(xiě)入敏感信息:

EMAIL_USER=your-email@gmail.com # 你的發(fā)件人郵箱
EMAIL_PASS=your-app-password    # 郵箱授權(quán)碼(非登錄密碼,Gmail需開(kāi)啟2FA后生成應(yīng)用專(zhuān)用密碼)

郵箱配置注意事項(xiàng)

  • Gmail:需開(kāi)啟“兩步驗(yàn)證”,并生成“應(yīng)用專(zhuān)用密碼”(登錄Gmail后,在“賬戶(hù)設(shè)置→安全”中配置)。
  • 國(guó)內(nèi)郵箱(如QQ、163):需在郵箱設(shè)置中開(kāi)啟“SMTP服務(wù)”,并獲取對(duì)應(yīng)的授權(quán)碼。

擴(kuò)展功能:可添加“附件發(fā)送”功能(在mailOptions中添加attachments: [{ filename: 'report.pdf', path: '/path/to/report.pdf' }])。

3. 目錄監(jiān)控腳本:實(shí)時(shí)跟蹤文件變化

在團(tuán)隊(duì)協(xié)作中,共享文件夾的文件修改、新增或刪除需要及時(shí)感知;開(kāi)發(fā)時(shí),也常需要監(jiān)控代碼目錄的變化以自動(dòng)觸發(fā)構(gòu)建。這個(gè)腳本基于Node.js的fs.watchAPI,能實(shí)時(shí)監(jiān)聽(tīng)指定目錄的文件事件,并輸出詳細(xì)的變化信息。

核心代碼

const fs = require('fs');
const path = require('path');

/**
 * 監(jiān)控目錄變化函數(shù)
 * @param {string} pathToWatch - 待監(jiān)控的目錄路徑(需替換為實(shí)際路徑)
 */
function monitorFolder(pathToWatch) {
  // 驗(yàn)證目錄是否存在
  if (!fs.existsSync(pathToWatch)) {
    throw new Error(`待監(jiān)控的目錄不存在:${pathToWatch}`);
  }

  console.log(`?? 已開(kāi)始監(jiān)控目錄:${pathToWatch}`);
  console.log('----------------------------------------');

  // 監(jiān)聽(tīng)目錄變化(支持rename和change兩種事件)
  fs.watch(pathToWatch, (eventType, filename) => {
    // eventType:事件類(lèi)型(rename=文件新增/刪除/重命名;change=文件內(nèi)容修改)
    // filename:發(fā)生變化的文件名(部分系統(tǒng)可能返回undefined,需處理)
    if (!filename) {
      console.log(`??  檢測(cè)到目錄變化,但未獲取到文件名`);
      return;
    }

    // 拼接完整的文件路徑
    const filePath = path.join(pathToWatch, filename);
    // 獲取當(dāng)前時(shí)間(用于日志記錄)
    const currentTime = new Date().toLocaleString();

    // 根據(jù)事件類(lèi)型輸出不同的日志
    switch (eventType) {
      case 'rename':
        // 檢查文件是否存在(存在=新增/重命名,不存在=刪除)
        const fileExists = fs.existsSync(filePath);
        console.log(`[${currentTime}] ?? ${fileExists ? '新增/重命名文件' : '刪除文件'}:${filename}`);
        break;
      case 'change':
        console.log(`[${currentTime}] ?? 修改文件內(nèi)容:${filename}`);
        break;
      default:
        console.log(`[${currentTime}] ??  未知事件類(lèi)型:${eventType},涉及文件:${filename}`);
    }
  });
}

// 配置待監(jiān)控的目錄(替換為你的實(shí)際目錄,如共享文檔或項(xiàng)目代碼目錄)
const targetFolder = '/Users/your-name/Shared/團(tuán)隊(duì)共享文件';
// 啟動(dòng)監(jiān)控
monitorFolder(targetFolder);

使用說(shuō)明與優(yōu)化建議

  • 運(yùn)行方式:保存為folder-monitor.js,執(zhí)行node folder-monitor.js,腳本會(huì)持續(xù)運(yùn)行并輸出目錄變化日志(按Ctrl+C終止)。
  • 典型用例
    • 監(jiān)控團(tuán)隊(duì)共享文件夾,及時(shí)發(fā)現(xiàn)同事上傳的新文件或修改的文檔。
    • 配合前端項(xiàng)目:監(jiān)控src目錄,當(dāng)代碼文件修改時(shí),自動(dòng)觸發(fā)webpack構(gòu)建(需額外集成構(gòu)建工具)。
  • 局限性fs.watch在部分系統(tǒng)(如Windows)對(duì)“子目錄變化”的監(jiān)聽(tīng)支持有限,若需監(jiān)控多級(jí)目錄,可使用第三方庫(kù)chokidarnpm install chokidar),其兼容性更強(qiáng)且支持遞歸監(jiān)聽(tīng)。

4. 圖像轉(zhuǎn)PDF腳本:批量生成掃描件或電子相冊(cè)

工作中常需要將多張掃描的圖片(如合同、發(fā)票)合并為一個(gè)PDF文件,方便歸檔與分享;生活中也可能需要將旅行照片整理成電子相冊(cè)。這個(gè)腳本基于pdfkit庫(kù),能自動(dòng)讀取指定目錄的所有圖片(支持JPG/PNG格式),按順序插入PDF并生成最終文件。

核心代碼

const fs = require('fs');
const path = require('path');
// 引入PDF生成庫(kù)pdfkit(需安裝:npm install pdfkit)
const PDFDocument = require('pdfkit');

/**
 * 批量將圖像轉(zhuǎn)換為PDF文件
 * @param {string} imageFolder - 存放圖像的目錄路徑(需替換為實(shí)際路徑)
 * @param {string} outputPDF - 生成的PDF文件路徑(如:"output.pdf")
 */
function imagesToPDF(imageFolder, outputPDF) {
  // 驗(yàn)證圖像目錄是否存在
  if (!fs.existsSync(imageFolder)) {
    throw new Error(`圖像目錄不存在:${imageFolder}`);
  }

  // 創(chuàng)建PDF文檔實(shí)例
  const doc = new PDFDocument({
    size: 'A4', // PDF頁(yè)面尺寸(可選:'A3'/'Letter'/'Legal'等)
    margin: 20 // 頁(yè)面邊距(避免圖片緊貼邊緣)
  });

  // 創(chuàng)建寫(xiě)入流,用于將PDF內(nèi)容寫(xiě)入文件
  const writeStream = fs.createWriteStream(outputPDF);
  doc.pipe(writeStream); // 將PDF文檔與寫(xiě)入流關(guān)聯(lián)

  // 讀取圖像目錄下的所有文件,并篩選出圖片文件
  fs.readdir(imageFolder, (err, files) => {
    if (err) throw new Error(`讀取圖像目錄失?。?{err.message}`);

    // 篩選JPG/JPEG/PNG格式的文件(不區(qū)分大小寫(xiě))
    const imageFiles = files.filter(file => 
      /\.(jpg|jpeg|png)$/i.test(path.extname(file))
    );

    if (imageFiles.length === 0) {
      console.warn('??  圖像目錄中未找到任何JPG/PNG文件');
      doc.end(); // 關(guān)閉PDF文檔
      return;
    }

    console.log(`?? 找到 ${imageFiles.length} 張圖片,開(kāi)始生成PDF...`);

    // 遍歷每張圖片,插入到PDF中
    imageFiles.forEach((file, index) => {
      const imagePath = path.join(imageFolder, file);

      // 除第一張圖片外,其余圖片均新增一頁(yè)(避免多圖擠在同一頁(yè))
      if (index !== 0) {
        doc.addPage(); // 新增PDF頁(yè)面
      }

      // 將圖片插入當(dāng)前頁(yè)面(配置自適應(yīng)尺寸與居中顯示)
      doc.image(imagePath, {
        fit: [550, 750], // 圖片最大尺寸(適配A4頁(yè)面,避免超出邊界)
        align: 'center', // 水平居中
        valign: 'center' // 垂直居中
      });

      // 在圖片下方添加文件名(可選,便于識(shí)別圖片來(lái)源)
      doc.moveDown(2) // 向下移動(dòng)2行距離
         .fontSize(10)
         .text(`圖片來(lái)源:${file}`, { align: 'center' });
    });

    // 結(jié)束PDF文檔生成
    doc.end();
  });

  // 監(jiān)聽(tīng)寫(xiě)入流完成事件(提示PDF生成成功)
  writeStream.on('finish', () => {
    console.log(`? PDF生成完成!文件路徑:${path.resolve(outputPDF)}`);
  });

  // 監(jiān)聽(tīng)寫(xiě)入流錯(cuò)誤事件(捕獲生成過(guò)程中的異常)
  writeStream.on('error', (err) => {
    console.error(`? PDF生成失?。?{err.message}`);
  });
}

// ------------------- 使用示例 -------------------
const imageDir = '/Users/your-name/Desktop/掃描件'; // 存放掃描圖片的目錄
const outputPath = '/Users/your-name/Desktop/掃描件合集.pdf'; // 生成的PDF路徑
imagesToPDF(imageDir, outputPath);

使用說(shuō)明與優(yōu)化建議

  • 前置準(zhǔn)備:執(zhí)行npm install pdfkit安裝依賴(lài),確保圖像目錄中的圖片格式為JPG或PNG(若需支持其他格式,可先通過(guò)圖像工具轉(zhuǎn)換)。
  • 優(yōu)化方向
    • 圖片排序:腳本默認(rèn)按文件名排序,若需按“修改時(shí)間”排序,可通過(guò)fs.stat獲取文件修改時(shí)間后再排序。
    • 壓縮圖片:若圖片體積過(guò)大導(dǎo)致PDF文件臃腫,可先使用sharp庫(kù)(npm install sharp)批量壓縮圖片,再執(zhí)行轉(zhuǎn)PDF操作。
  • 典型場(chǎng)景:掃描合同后生成統(tǒng)一的PDF文件、將手機(jī)拍攝的紙質(zhì)文檔圖片整理為可打印的PDF、制作旅行照片電子相冊(cè)等。

5. 桌面通知提醒腳本:重要事項(xiàng)不再錯(cuò)過(guò)

工作中的會(huì)議、待辦事項(xiàng),生活中的約會(huì)、提醒,都可能因忙碌而遺忘。這個(gè)腳本基于node-notifier庫(kù),支持設(shè)置未來(lái)時(shí)間,在指定時(shí)刻彈出系統(tǒng)桌面通知(支持Windows、Mac、Linux),并可配置提示音,確保你不會(huì)錯(cuò)過(guò)任何重要事項(xiàng)。

核心代碼

// 引入桌面通知庫(kù)(需安裝:npm install node-notifier)
const notifier = require('node-notifier');
const path = require('path');

/**
 * 桌面通知提醒函數(shù)
 * @param {string} title - 通知標(biāo)題(如:"會(huì)議提醒")
 * @param {string} message - 通知內(nèi)容(如:"下午3點(diǎn)項(xiàng)目會(huì)議")
 * @param {number} notificationTime - 通知觸發(fā)時(shí)間(毫秒級(jí)時(shí)間戳)
 * @param {string} [soundPath] - 提示音路徑(可選,支持mp3/wav格式)
 */
function desktopNotifier(title, message, notificationTime, soundPath) {
  // 計(jì)算延遲時(shí)間(當(dāng)前時(shí)間到通知時(shí)間的差值)
  const delay = notificationTime - Date.now();

  // 處理延遲為負(fù)的情況(通知時(shí)間已過(guò))
  if (delay < 0) {
    console.error('? 錯(cuò)誤:通知時(shí)間已過(guò)期,請(qǐng)?jiān)O(shè)置未來(lái)的時(shí)間');
    return;
  }

  console.log(`? 已預(yù)約通知:【${title}】,將在 ${new Date(notificationTime).toLocaleString()} 提醒`);

  // 延遲指定時(shí)間后觸發(fā)通知
  setTimeout(() => {
    // 配置通知選項(xiàng)
    const notificationOptions = {
      title: title, // 通知標(biāo)題
      message: message, // 通知內(nèi)容(支持換行,用\n分隔)
      icon: path.join(__dirname, 'reminder-icon.png'), // 通知圖標(biāo)(可選,替換為你的圖標(biāo)路徑)
      sound: soundPath ? soundPath : true, // 提示音(true表示使用系統(tǒng)默認(rèn)提示音)
      wait: true, // 點(diǎn)擊通知后才關(guān)閉(避免被忽略)
    };

    // 發(fā)送桌面通知
    notifier.notify(notificationOptions, (err, response) => {
      if (err) {
        console.error(`? 通知發(fā)送失敗:${err.message}`);
      } else {
        console.log(`? 通知已發(fā)送!用戶(hù)響應(yīng):${response}`);
      }
    });

    // 監(jiān)聽(tīng)通知的點(diǎn)擊事件(可選,如點(diǎn)擊后打開(kāi)相關(guān)文件/鏈接)
    notifier.on('click', () => {
      console.log(`?? 用戶(hù)點(diǎn)擊了【${title}】通知`);
      // 示例:點(diǎn)擊通知后打開(kāi)瀏覽器訪問(wèn)指定鏈接(需引入open庫(kù):npm install open)
      // const open = require('open');
      // open('https://docs.google.com/document/d/xxx'); // 如打開(kāi)會(huì)議文檔
    });
  }, delay);
}

// ------------------- 使用示例 -------------------
// 1. 設(shè)置通知時(shí)間:15秒后觸發(fā)(Date.now() + 15000毫秒)
const remindTime = Date.now() + 15000;

// 2. 調(diào)用函數(shù)發(fā)送預(yù)約通知
desktopNotifier(
  '團(tuán)隊(duì)會(huì)議提醒', // 通知標(biāo)題
  '?? 下午3點(diǎn)在會(huì)議室A召開(kāi)項(xiàng)目進(jìn)度會(huì)議\n?? 請(qǐng)?zhí)崆皽?zhǔn)備上周進(jìn)度報(bào)告', // 通知內(nèi)容(支持換行)
  remindTime, // 通知時(shí)間
  // path.join(__dirname, 'reminder-sound.mp3') // 可選:自定義提示音路徑
);

使用說(shuō)明與優(yōu)化建議

前置準(zhǔn)備

  • 安裝依賴(lài):npm install node-notifier(若需點(diǎn)擊通知打開(kāi)鏈接,額外安裝npm install open)。
  • 通知圖標(biāo)(可選):準(zhǔn)備一張PNG格式的圖標(biāo)文件(建議尺寸256x256),放在腳本同級(jí)目錄,修改icon路徑為實(shí)際文件名。

系統(tǒng)兼容性

  • Mac:通知會(huì)顯示在右上角,支持提示音;
  • Windows:通知顯示在右下角(操作中心),需確保“通知”權(quán)限已開(kāi)啟;
  • Linux:依賴(lài)libnotify-bin,需先執(zhí)行sudo apt-get install libnotify-bin安裝。

擴(kuò)展場(chǎng)景:可結(jié)合“日歷API”(如Google Calendar)獲取日程,自動(dòng)生成通知;或配合“待辦事項(xiàng)列表”,到期自動(dòng)提醒。

6. 自動(dòng)清理舊文件腳本:釋放磁盤(pán)空間,告別文件堆積

電腦使用時(shí)間久了,下載目錄、日志目錄常會(huì)堆積大量過(guò)期文件(如1個(gè)月前的安裝包、半年前的日志),占用寶貴的磁盤(pán)空間。這個(gè)腳本能自動(dòng)掃描指定目錄,刪除超過(guò)設(shè)定天數(shù)的文件,幫你定期“斷舍離”,保持磁盤(pán)整潔。

核心代碼

const fs = require('fs');
const path = require('path');

/**
 * 自動(dòng)清理舊文件函數(shù)
 * @param {string} folder - 待清理的目錄路徑(需替換為實(shí)際路徑)
 * @param {number} days - 過(guò)期天數(shù)(超過(guò)此天數(shù)的文件將被刪除)
 * @param {boolean} [dryRun=false] - 模擬清理(true=只打印要?jiǎng)h除的文件,不實(shí)際刪除)
 */
function cleanOldFiles(folder, days, dryRun = false) {
  // 驗(yàn)證目錄是否存在
  if (!fs.existsSync(folder)) {
    throw new Error(`待清理的目錄不存在:${folder}`);
  }

  // 計(jì)算“過(guò)期時(shí)間點(diǎn)”(當(dāng)前時(shí)間 - 天數(shù)×毫秒數(shù))
  const now = Date.now();
  const cutoffTime = now - days * 24 * 60 * 60 * 1000; // 1天=24h×60min×60s×1000ms

  console.log(`???  開(kāi)始清理目錄:${folder}`);
  console.log(`? 清理規(guī)則:刪除超過(guò) ${days} 天未修改的文件`);
  console.log(`?? 過(guò)期時(shí)間點(diǎn):${new Date(cutoffTime).toLocaleString()}`);
  console.log(`?? 正在掃描文件...`);

  // 讀取目錄下的所有文件/文件夾
  fs.readdir(folder, (err, files) => {
    if (err) throw new Error(`讀取清理目錄失?。?{err.message}`);

    // 存儲(chǔ)待刪除的文件列表(用于最終統(tǒng)計(jì))
    const filesToDelete = [];

    // 遍歷每個(gè)文件,檢查是否過(guò)期
    files.forEach((file) => {
      const filePath = path.join(folder, file);

      // 獲取文件的狀態(tài)信息(如修改時(shí)間、是否為目錄)
      fs.stat(filePath, (err, stat) => {
        if (err) {
          console.error(`?? 獲取文件 ${file} 狀態(tài)失敗:${err.message}`);
          return;
        }

        // 跳過(guò)目錄(只刪除文件,不刪除子目錄)
        if (stat.isDirectory()) {
          console.log(`?? 跳過(guò)目錄:${file}`);
          return;
        }

        // 檢查文件修改時(shí)間是否早于過(guò)期時(shí)間點(diǎn)
        const fileModifyTime = stat.mtime.getTime();
        if (fileModifyTime < cutoffTime) {
          filesToDelete.push(file);
          // 若不是模擬清理,則執(zhí)行刪除操作
          if (!dryRun) {
            fs.unlink(filePath, (err) => {
              if (err) {
                console.error(`? 刪除文件 ${file} 失?。?{err.message}`);
              } else {
                console.log(`? 已刪除過(guò)期文件:${file}(最后修改時(shí)間:${new Date(fileModifyTime).toLocaleString()})`);
              }
            });
          } else {
            // 模擬清理:只打印,不刪除
            console.log(`?? 模擬刪除:${file}(最后修改時(shí)間:${new Date(fileModifyTime).toLocaleString()})`);
          }
        }
      });
    });

    // 掃描完成后輸出統(tǒng)計(jì)信息(延遲1秒,確保文件狀態(tài)讀取完成)
    setTimeout(() => {
      console.log('----------------------------------------');
      console.log(`?? 掃描完成!共發(fā)現(xiàn) ${filesToDelete.length} 個(gè)過(guò)期文件`);
      if (dryRun) {
        console.log(`??  提示:當(dāng)前為模擬清理模式,未實(shí)際刪除文件。若需執(zhí)行刪除,請(qǐng)將dryRun設(shè)為false。`);
      }
    }, 1000);
  });
}

// ------------------- 使用示例 -------------------
const targetDir = '/Users/your-name/Downloads'; // 待清理目錄(如下載目錄)
const expireDays = 30; // 清理超過(guò)30天的文件
const isDryRun = true; // 先執(zhí)行模擬清理(確認(rèn)無(wú)誤后改為false)

// 執(zhí)行清理(首次使用建議先模擬,避免誤刪重要文件)
cleanOldFiles(targetDir, expireDays, isDryRun);

使用說(shuō)明與優(yōu)化建議

安全提示

  • 首次使用務(wù)必設(shè)置isDryRun = true,先模擬清理(只打印待刪除文件),確認(rèn)無(wú)重要文件后再改為false執(zhí)行實(shí)際刪除。
  • 避免直接清理系統(tǒng)目錄(如C:\Windows/usr),防止誤刪系統(tǒng)文件導(dǎo)致崩潰。

定時(shí)清理:結(jié)合Linux的cron或Windows的任務(wù)計(jì)劃,設(shè)置每月1日自動(dòng)清理下載目錄(如0 0 1 * * node /path/to/clean-old-files.js)。

擴(kuò)展功能:可添加“白名單”功能(如const whitelist = ['important-file.txt', 'backup.zip']),跳過(guò)無(wú)需刪除的關(guān)鍵文件。

7. 文本文件翻譯腳本:快速實(shí)現(xiàn)多語(yǔ)言轉(zhuǎn)換

工作中常需要翻譯英文文檔、產(chǎn)品說(shuō)明,或把中文內(nèi)容翻譯成其他語(yǔ)言。這個(gè)腳本基于免費(fèi)的LibreTranslateAPI,支持將文本文件從一種語(yǔ)言翻譯為另一種語(yǔ)言(如英文→中文、中文→西班牙語(yǔ)),無(wú)需手動(dòng)復(fù)制粘貼到翻譯工具,高效且免費(fèi)。

核心代碼

const fs = require('fs');
const path = require('path');
// 引入HTTP請(qǐng)求庫(kù)axios(需安裝:npm install axios)
const axios = require('axios');

/**
 * 翻譯文本函數(shù)(基于LibreTranslate免費(fèi)API)
 * @param {string} text - 待翻譯的文本內(nèi)容
 * @param {string} sourceLang - 源語(yǔ)言(如:"en"=英文,"zh"=中文,"es"=西班牙語(yǔ))
 * @param {string} targetLang - 目標(biāo)語(yǔ)言(同上)
 * @returns {Promise<string>} 翻譯后的文本
 */
async function translateText(text, sourceLang = 'en', targetLang = 'zh') {
  try {
    // 發(fā)送POST請(qǐng)求到LibreTranslate API(免費(fèi),無(wú)需API密鑰)
    const response = await axios.post('https://libretranslate.de/translate', {
      q: text, // 待翻譯文本
      source: sourceLang, // 源語(yǔ)言
      target: targetLang, // 目標(biāo)語(yǔ)言
      format: 'text', // 文本格式(支持"text"或"html")
    });

    // 返回翻譯后的文本
    return response.data.translatedText;
  } catch (err) {
    throw new Error(`翻譯失敗:${err.response?.data?.error || err.message}`);
  }
}

/**
 * 翻譯文本文件(批量處理整個(gè)文件)
 * @param {string} inputPath - 輸入文本文件路徑(如:"original.txt")
 * @param {string} outputPath - 輸出翻譯文件路徑(如:"translated-zh.txt")
 * @param {string} sourceLang - 源語(yǔ)言
 * @param {string} targetLang - 目標(biāo)語(yǔ)言
 */
async function translateTextFile(inputPath, outputPath, sourceLang, targetLang) {
  // 驗(yàn)證輸入文件是否存在
  if (!fs.existsSync(inputPath)) {
    throw new Error(`輸入文件不存在:${inputPath}`);
  }

  console.log(`?? 開(kāi)始翻譯文件:${inputPath}`);
  console.log(`?? 翻譯方向:${sourceLang} → ${targetLang}`);

  try {
    // 1. 讀取輸入文件的文本內(nèi)容(支持UTF-8編碼)
    const originalText = fs.readFileSync(inputPath, 'utf8');
    console.log(`?? 成功讀取輸入文件,文本長(zhǎng)度:${originalText.length} 字符`);

    // 2. 調(diào)用翻譯函數(shù)處理文本
    const translatedText = await translateText(originalText, sourceLang, targetLang);

    // 3. 將翻譯后的文本寫(xiě)入輸出文件
    fs.writeFileSync(outputPath, translatedText, 'utf8');
    console.log(`? 翻譯完成!輸出文件路徑:${path.resolve(outputPath)}`);
  } catch (err) {
    console.error(`? 翻譯文件失?。?{err.message}`);
  }
}

// ------------------- 使用示例 -------------------
// 示例1:將英文文件翻譯成中文
translateTextFile(
  '/Users/your-name/Documents/product-en.txt', // 輸入英文文件
  '/Users/your-name/Documents/product-zh.txt', // 輸出中文文件
  'en', // 源語(yǔ)言:英文
  'zh'  // 目標(biāo)語(yǔ)言:中文
);

// 示例2:將中文文件翻譯成西班牙語(yǔ)(需將sourceLang改為"zh",targetLang改為"es")
// translateTextFile(
//   '/Users/your-name/Documents/notes-zh.txt',
//   '/Users/your-name/Documents/notes-es.txt',
//   'zh',
//   'es'
// );

使用說(shuō)明與優(yōu)化建議

  • API說(shuō)明LibreTranslate是免費(fèi)開(kāi)源的翻譯API,無(wú)需注冊(cè)密鑰,適合小型翻譯需求(單請(qǐng)求文本長(zhǎng)度有限制,若翻譯大文件需分割文本)。若需更高穩(wěn)定性與更長(zhǎng)文本支持,可改用Google Translate API(需注冊(cè)并獲取API密鑰,收費(fèi)但額度較低時(shí)免費(fèi))。
  • 支持語(yǔ)言LibreTranslate支持20+種語(yǔ)言,常見(jiàn)語(yǔ)言代碼:英文(en)、中文(zh)、西班牙語(yǔ)(es)、法語(yǔ)(fr)、德語(yǔ)(de)、日語(yǔ)(ja)等。
  • 大文件處理:若輸入文件過(guò)大(如超過(guò)5000字符),可添加“文本分割”邏輯,將文本按段落或句子分割后逐段翻譯,最后合并結(jié)果。

8. 多PDF合并腳本:一鍵整合分散的PDF文檔

工作中常需要將多個(gè)分散的PDF文件(如項(xiàng)目報(bào)告的各個(gè)章節(jié)、多份發(fā)票)合并為一個(gè)完整文件,方便分享與打印。這個(gè)腳本基于pdf-merger-js庫(kù),支持批量讀取指定目錄的所有PDF,按順序合并為一個(gè)文件,且支持自定義合并順序。

核心代碼

const fs = require('fs');
const path = require('path');
// 引入PDF合并庫(kù)(需安裝:npm install pdf-merger-js)
const PDFMerger = require('pdf-merger-js');

/**
 * 批量合并PDF文件
 * @param {string} pdfFolder - 存放待合并PDF的目錄路徑
 * @param {string} outputPDF - 合并后的輸出PDF路徑
 * @param {function} [sortFn] - 自定義排序函數(shù)(可選,用于調(diào)整PDF合并順序)
 */
async function mergePDFs(pdfFolder, outputPDF, sortFn) {
  // 驗(yàn)證PDF目錄是否存在
  if (!fs.existsSync(pdfFolder)) {
    throw new Error(`PDF目錄不存在:${pdfFolder}`);
  }

  // 1. 讀取目錄下的所有PDF文件
  const files = fs.readdirSync(pdfFolder);
  // 篩選出后綴為.pdf的文件(不區(qū)分大小寫(xiě))
  let pdfFiles = files.filter(file => 
    path.extname(file).toLowerCase() === '.pdf'
  );

  // 若未找到PDF文件,拋出錯(cuò)誤
  if (pdfFiles.length === 0) {
    throw new Error(`PDF目錄中未找到任何PDF文件:${pdfFolder}`);
  }

  // 2. 按自定義規(guī)則排序(默認(rèn)按文件名升序,可選傳入sortFn調(diào)整順序)
  if (sortFn && typeof sortFn === 'function') {
    pdfFiles.sort(sortFn);
  } else {
    // 默認(rèn)按文件名升序排序(如:1.pdf → 2.pdf → 3.pdf)
    pdfFiles.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
  }

  console.log(`?? 找到 ${pdfFiles.length} 個(gè)待合并PDF文件`);
  console.log(`?? 合并順序:${pdfFiles.join(' → ')}`);

  // 3. 創(chuàng)建PDF合并實(shí)例
  const merger = new PDFMerger();

  try {
    // 遍歷PDF文件,添加到合并隊(duì)列
    for (const file of pdfFiles) {
      const pdfPath = path.join(pdfFolder, file);
      // 驗(yàn)證文件是否為有效PDF(避免目錄或非PDF文件)
      if (fs.statSync(pdfPath).isFile()) {
        await merger.add(pdfPath); // 添加PDF到合并隊(duì)列
        console.log(`? 已添加:${file}`);
      }
    }

    // 4. 執(zhí)行合并并保存到輸出文件
    await merger.save(outputPDF);
    console.log(`?? PDF合并完成!輸出路徑:${path.resolve(outputPDF)}`);
  } catch (err) {
    throw new Error(`PDF合并失?。?{err.message}`);
  }
}

// ------------------- 使用示例 -------------------
// 示例1:默認(rèn)按文件名升序合并(如:chapter1.pdf → chapter2.pdf)
const pdfDir = '/Users/your-name/Documents/項(xiàng)目報(bào)告章節(jié)'; // 待合并PDF目錄
const outputPath = '/Users/your-name/Documents/項(xiàng)目報(bào)告-完整版.pdf'; // 輸出路徑

// 執(zhí)行合并(默認(rèn)排序)
mergePDFs(pdfDir, outputPath)
  .catch(err => console.error(`? 操作失?。?{err.message}`));

// 示例2:按“文件修改時(shí)間”排序(最新修改的PDF排在前面)
// mergePDFs(
//   pdfDir,
//   outputPath,
//   (a, b) => {
//     // 獲取兩個(gè)文件的修改時(shí)間
//     const timeA = fs.statSync(path.join(pdfDir, a)).mtime.getTime();
//     const timeB = fs.statSync(path.join(pdfDir, b)).mtime.getTime();
//     return timeB - timeA; // 降序排序(最新的在前)
//   }
// ).catch(err => console.error(`? 操作失?。?{err.message}`));

使用說(shuō)明與優(yōu)化建議

  • 前置準(zhǔn)備:安裝依賴(lài)npm install pdf-merger-js,確保待合并的PDF文件無(wú)損壞(若某文件損壞,會(huì)導(dǎo)致合并失敗,需先修復(fù)或移除該文件)。
  • 排序需求
    • 按文件名排序:適合文件命名有規(guī)律的場(chǎng)景(如chapter1.pdf、chapter2.pdf)。
    • 按修改時(shí)間排序:適合需要優(yōu)先合并最新編輯的PDF場(chǎng)景(如最新的發(fā)票排在前面)。
    • 自定義順序:可傳入排序函數(shù),如按文件大小、按特定關(guān)鍵詞(如“封面”“正文”“附錄”)排序。
  • 大型PDF處理:若合并的PDF文件較多或體積較大,建議確保Node.js內(nèi)存充足(可通過(guò)node --max-old-space-size=4096 merge-pdfs.js增加內(nèi)存限制)。

9. 批量重命名文件腳本:規(guī)范文件命名,提升管理效率

下載的圖片、視頻或文檔常存在命名混亂的問(wèn)題(如IMG_20240515.jpg未命名文件1.pdf),不利于查找與管理。這個(gè)腳本能按指定前綴和序號(hào)批量重命名文件(如report_001.pdf、report_002.pdf),支持自定義前綴、序號(hào)位數(shù),且能保留文件原始擴(kuò)展名。

核心代碼

const fs = require('fs');
const path = require('path');

/**
 * 批量重命名文件函數(shù)
 * @param {string} folder - 待重命名文件所在的目錄路徑
 * @param {string} prefix - 新文件名的前綴(如:"image" → "image_001.jpg")
 * @param {number} [startIndex=1] - 起始序號(hào)(默認(rèn)從1開(kāi)始)
 * @param {number} [digitLength=3] - 序號(hào)位數(shù)(默認(rèn)3位,如:001、002)
 * @param {string[]} [excludeExts=[]] - 排除的文件擴(kuò)展名(如:['.txt'],不重命名txt文件)
 */
function batchRename(folder, prefix, startIndex = 1, digitLength = 3, excludeExts = []) {
  // 驗(yàn)證目錄是否存在
  if (!fs.existsSync(folder)) {
    throw new Error(`待重命名的目錄不存在:${folder}`);
  }

  // 讀取目錄下的所有文件(不包含子目錄)
  fs.readdir(folder, (err, files) => {
    if (err) throw new Error(`讀取目錄失敗:${err.message}`);

    // 過(guò)濾掉目錄,只保留文件
    const fileList = files.filter(file => 
      fs.statSync(path.join(folder, file)).isFile()
    );

    if (fileList.length === 0) {
      console.warn('??  目錄中未找到任何文件,無(wú)需重命名');
      return;
    }

    console.log(`?? 開(kāi)始批量重命名目錄:${folder}`);
    console.log(`?? 重命名規(guī)則:${prefix}_[序號(hào)].擴(kuò)展名(序號(hào)從${startIndex}開(kāi)始,共${digitLength}位)`);
    console.log(`?? 排除的擴(kuò)展名:${excludeExts.length > 0 ? excludeExts.join(', ') : '無(wú)'}`);
    console.log('----------------------------------------');

    // 遍歷文件,執(zhí)行重命名
    fileList.forEach((oldFileName, index) => {
      // 1. 獲取文件原始擴(kuò)展名(如:.jpg、.pdf)
      const ext = path.extname(oldFileName).toLowerCase();

      // 2. 檢查是否需要排除該擴(kuò)展名
      if (excludeExts.includes(ext)) {
        console.log(`??  排除文件:${oldFileName}(擴(kuò)展名${ext}在排除列表中)`);
        return;
      }

      // 3. 計(jì)算當(dāng)前文件的序號(hào)(起始序號(hào) + 索引)
      const currentIndex = startIndex + index;
      // 用0填充序號(hào),確保位數(shù)統(tǒng)一(如:1 → 001,10 → 010)
      const paddedIndex = String(currentIndex).padStart(digitLength, '0');

      // 4. 拼接新文件名(前綴 + 序號(hào) + 原始擴(kuò)展名)
      const newFileName = `${prefix}_${paddedIndex}${ext}`;

      // 5. 拼接舊路徑與新路徑
      const oldPath = path.join(folder, oldFileName);
      const newPath = path.join(folder, newFileName);

      // 6. 避免新文件名與現(xiàn)有文件沖突
      if (fs.existsSync(newPath) && oldPath !== newPath) {
        console.error(`? 重命名失?。?{newFileName} 已存在,跳過(guò) ${oldFileName}`);
        return;
      }

      // 7. 執(zhí)行重命名操作
      fs.rename(oldPath, newPath, (err) => {
        if (err) {
          console.error(`? 重命名 ${oldFileName} 失?。?{err.message}`);
        } else {
          console.log(`? 重命名成功:${oldFileName} → ${newFileName}`);
        }
      });
    });
  });
}

// ------------------- 使用示例 -------------------
// 示例1:批量重命名下載的圖片(前綴"vacation_photo",序號(hào)3位,排除.txt文件)
batchRename(
  '/Users/your-name/Downloads/旅行照片', // 待重命名目錄
  'vacation_photo', // 文件名前綴
  1, // 起始序號(hào)
  3, // 序號(hào)位數(shù)(001~999)
  ['.txt'] // 排除.txt文件(不重命名文本文件)
);

// 示例2:重命名項(xiàng)目文檔(前綴"project_report",序號(hào)2位,從10開(kāi)始)
// batchRename(
//   '/Users/your-name/Documents/項(xiàng)目文檔',
//   'project_report',
//   10, // 起始序號(hào)10 → 10、11、12...
//   2, // 序號(hào)位數(shù)(01~99,10 → 10,11 → 11)
//   [] // 不排除任何擴(kuò)展名
// );

使用說(shuō)明與優(yōu)化建議

  • 關(guān)鍵參數(shù)說(shuō)明
    • prefix:根據(jù)文件類(lèi)型命名(如圖片用image,文檔用document),便于識(shí)別。
    • digitLength:序號(hào)位數(shù)建議根據(jù)文件數(shù)量設(shè)置(如100個(gè)文件用3位,避免100 → 00100的問(wèn)題)。
    • excludeExts:用于保留目錄中的關(guān)鍵文件(如README.txt,避免被誤重命名)。
  • 避免沖突:腳本會(huì)檢查新文件名是否已存在,若存在則跳過(guò)該文件,防止覆蓋現(xiàn)有文件。
  • 擴(kuò)展功能:可添加“按文件類(lèi)型分類(lèi)重命名”(如圖片用image_xxx,PDF用pdf_xxx),通過(guò)判斷ext來(lái)動(dòng)態(tài)設(shè)置prefix

10. 天氣數(shù)據(jù)抓取腳本:實(shí)時(shí)獲取城市天氣信息

出門(mén)前查看天氣、安排出差時(shí)了解目的地氣候,都需要實(shí)時(shí)天氣數(shù)據(jù)。這個(gè)腳本基于OpenWeatherMapAPI,支持通過(guò)城市名獲取當(dāng)前天氣(溫度、天氣狀況、濕度等),并以清晰的格式輸出,還可擴(kuò)展為“定時(shí)推送天氣到郵箱”的功能。

核心代碼

const axios = require('axios');

/**
 * 獲取指定城市的當(dāng)前天氣信息
 * @param {string} city - 城市名稱(chēng)(如:"New York"、"Beijing")
 * @param {string} apiKey - OpenWeatherMap API密鑰(需自行注冊(cè)獲?。?
 * @param {string} [units=metric] - 溫度單位(metric=攝氏度,imperial=華氏度)
 * @param {string} [lang=zh_cn] - 語(yǔ)言(zh_cn=中文,en=英文)
 */
async function getWeather(city, apiKey, units = 'metric', lang = 'zh_cn') {
  // 驗(yàn)證API密鑰是否存在(需用戶(hù)自行注冊(cè)獲?。?
  if (!apiKey) {
    throw new Error('請(qǐng)?zhí)峁㎡penWeatherMap API密鑰(注冊(cè)地址:https://openweathermap.org/)');
  }

  try {
    // 調(diào)用OpenWeatherMap API獲取天氣數(shù)據(jù)
    const response = await axios.get('https://api.openweathermap.org/data/2.5/weather', {
      params: {
        q: city, // 城市名
        appid: apiKey, // API密鑰
        units: units, // 溫度單位
        lang: lang // 響應(yīng)語(yǔ)言
      }
    });

    // 提取關(guān)鍵天氣數(shù)據(jù)(從API響應(yīng)中篩選有用信息)
    const weatherData = response.data;
    const { temp, feels_like, humidity, pressure } = weatherData.main; // 溫度、體感溫度、濕度、氣壓
    const { description, icon } = weatherData.weather[0]; // 天氣狀況描述、圖標(biāo)
    const { speed } = weatherData.wind; // 風(fēng)速
    const { country } = weatherData.sys; // 國(guó)家代碼
    const sunriseTime = new Date(weatherData.sys.sunrise * 1000).toLocaleTimeString(); // 日出時(shí)間
    const sunsetTime = new Date(weatherData.sys.sunset * 1000).toLocaleTimeString(); // 日落時(shí)間

    // 格式化輸出天氣信息
    console.log(`???  ${city}, ${country} 當(dāng)前天氣`);
    console.log('----------------------------------------');
    console.log(`天氣狀況:${description.charAt(0).toUpperCase() + description.slice(1)}`); // 首字母大寫(xiě)
    console.log(`當(dāng)前溫度:${temp} °C(體感溫度:${feels_like} °C)`);
    console.log(`濕度:${humidity}% | 氣壓:${pressure} hPa | 風(fēng)速:${speed} m/s`);
    console.log(`日出時(shí)間:${sunriseTime} | 日落時(shí)間:${sunsetTime}`);
    console.log('----------------------------------------');

    // 返回完整天氣數(shù)據(jù)(便于后續(xù)擴(kuò)展,如寫(xiě)入文件或發(fā)送郵件)
    return weatherData;
  } catch (err) {
    // 處理API調(diào)用錯(cuò)誤(如城市不存在、API密鑰無(wú)效)
    const errorMsg = err.response?.data?.message || err.message;
    throw new Error(`獲取天氣失?。?{errorMsg}`);
  }
}

// ------------------- 使用示例 -------------------
// 1. 替換為你的OpenWeatherMap API密鑰(免費(fèi)注冊(cè)獲取:https://openweathermap.org/api)
const apiKey = 'your-openweathermap-api-key';

// 2. 獲取指定城市的天氣(示例:北京)
getWeather('Beijing', apiKey)
  .then(() => console.log('? 天氣數(shù)據(jù)獲取完成'))
  .catch(err => console.error(`? 操作失?。?{err.message}`));

// 3. 獲取其他城市天氣(示例:紐約,英文輸出,華氏度)
// getWeather('New York', apiKey, 'imperial', 'en')
//   .then(() => console.log('? Weather data retrieved successfully'))
//   .catch(err => console.error(`? Failed: ${err.message}`));

使用說(shuō)明與優(yōu)化建議

API密鑰獲取

  • 訪問(wèn)OpenWeatherMap官網(wǎng)注冊(cè)賬號(hào)。
  • 登錄后,在“API Keys”頁(yè)面生成免費(fèi)API密鑰(免費(fèi)版支持每小時(shí)60次請(qǐng)求,足夠個(gè)人使用)。

擴(kuò)展功能

  • 定時(shí)推送:結(jié)合“自動(dòng)發(fā)送郵件腳本”,每天早上8點(diǎn)將天氣信息發(fā)送到郵箱。
  • 多城市查詢(xún):傳入城市數(shù)組(如['Beijing', 'Shanghai', 'Guangzhou']),批量獲取多個(gè)城市天氣。
  • 天氣圖標(biāo):API返回的icon字段可用于拼接圖標(biāo)URL(如https://openweathermap.org/img/wn/${icon}@2x.png),在控制臺(tái)或前端頁(yè)面顯示天氣圖標(biāo)。

11. 隨機(jī)名言生成腳本:獲取靈感,點(diǎn)綴你的工作環(huán)境

工作疲勞時(shí),一句勵(lì)志或富有哲理的名言能帶來(lái)靈感與動(dòng)力。這個(gè)腳本基于quotable免費(fèi)API,支持隨機(jī)獲取名言、作者信息,可用于終端美化、桌面壁紙生成,或集成到項(xiàng)目中作為歡迎語(yǔ)。

核心代碼

const axios = require('axios');

/**
 * 獲取隨機(jī)名言(支持篩選標(biāo)簽、作者)
 * @param {string[]} [tags=[]] - 篩選標(biāo)簽(如:["inspirational", "life"],勵(lì)志、人生主題)
 * @param {string} [author=undefined] - 篩選作者(如:"Albert Einstein",只獲取該作者的名言)
 * @returns {Promise<object>} 名言對(duì)象(包含content=名言?xún)?nèi)容,author=作者,tags=標(biāo)簽)
 */
async function getRandomQuote(tags = [], author = undefined) {
  try {
    // 構(gòu)建API請(qǐng)求參數(shù)
    const params = {};
    // 若有標(biāo)簽篩選,拼接標(biāo)簽參數(shù)(多個(gè)標(biāo)簽用逗號(hào)分隔)
    if (tags.length > 0) params.tags = tags.join(',');
    // 若有作者篩選,添加作者參數(shù)
    if (author) params.author = author;

    // 調(diào)用quotable API獲取隨機(jī)名言(免費(fèi),無(wú)需API密鑰)
    const response = await axios.get('https://api.quotable.io/random', { params });
    const quote = response.data;

    // 格式化輸出名言(帶樣式,便于閱讀)
    console.log('========================================');
    console.log(`"${quote.content}"`);
    console.log(`\n— ${quote.author}`);
    if (quote.tags.length > 0) {
      console.log(`\n主題:${quote.tags.map(tag => `#${tag}`).join(' ')}`);
    }
    console.log('========================================');

    // 返回名言對(duì)象(便于后續(xù)擴(kuò)展,如寫(xiě)入文件、生成圖片)
    return quote;
  } catch (err) {
    const errorMsg = err.response?.data?.message || err.message;
    throw new Error(`獲取名言失敗:${errorMsg}`);
  }
}

// ------------------- 使用示例 -------------------
// 示例1:獲取任意隨機(jī)名言(無(wú)篩選)
console.log('?? 獲取任意隨機(jī)名言:');
getRandomQuote()
  .then(() => console.log('? 名言獲取完成'))
  .catch(err => console.error(`? 操作失?。?{err.message}`));

// 示例2:獲取“勵(lì)志”主題的名言(標(biāo)簽篩選)
// console.log('\n?? 獲取勵(lì)志主題名言:');
// getRandomQuote(['inspirational'])
//   .then(() => console.log('? 名言獲取完成'))
//   .catch(err => console.error(`? 操作失敗:${err.message}`));

// 示例3:獲取愛(ài)因斯坦的名言(作者篩選)
// console.log('\n?? 獲取愛(ài)因斯坦的名言:');
// getRandomQuote([], 'Albert Einstein')
//   .then(() => console.log('? 名言獲取完成'))
//   .catch(err => console.error(`? 操作失?。?{err.message}`));

使用說(shuō)明與優(yōu)化建議

API特點(diǎn)quotable是免費(fèi)開(kāi)源的名言API,無(wú)需注冊(cè)密鑰,包含數(shù)千條來(lái)自不同作者的名言,支持按主題、作者、長(zhǎng)度篩選。

支持標(biāo)簽:常見(jiàn)標(biāo)簽包括inspirational(勵(lì)志)、life(人生)、love(愛(ài)情)、success(成功)、happiness(幸福)等,完整標(biāo)簽列表可查看quotable文檔。

擴(kuò)展場(chǎng)景

  • 終端啟動(dòng)名言:在.bashrc(Linux/Mac)或profile.ps1(Windows PowerShell)中添加node /path/to/random-quote.js,每次打開(kāi)終端自動(dòng)顯示一句名言。
  • 名言圖片生成:結(jié)合sharp庫(kù),將名言與背景圖合成,生成可分享的圖片。

以上就是11個(gè)JavaScript實(shí)用自動(dòng)化腳本(文件管理,通知提醒,數(shù)據(jù)抓取)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript自動(dòng)化腳本的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 關(guān)于在LayUI中使用AJAX提交巨坑記錄

    關(guān)于在LayUI中使用AJAX提交巨坑記錄

    今天小編就為大家分享一篇關(guān)于在LayUI中使用AJAX提交巨坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-10-10
  • 微信小程序如何實(shí)現(xiàn)全局重新加載

    微信小程序如何實(shí)現(xiàn)全局重新加載

    這篇文章主要給大家介紹了關(guān)于微信小程序如何實(shí)現(xiàn)全局重新加載的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用微信小程序具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • JavaScript中如何判斷一個(gè)值的類(lèi)型

    JavaScript中如何判斷一個(gè)值的類(lèi)型

    在js中有一個(gè)運(yùn)算符可以幫助我們判斷一個(gè)值的類(lèi)型,它就是typeof運(yùn)算符。下面通過(guò)本文給大家分享JavaScript中如何判斷一個(gè)值的類(lèi)型,需要的朋友參考下吧
    2017-09-09
  • js調(diào)用webservice中的方法實(shí)現(xiàn)思路及代碼

    js調(diào)用webservice中的方法實(shí)現(xiàn)思路及代碼

    js調(diào)用webservice還算是一個(gè)比較實(shí)用的功能,本文提供了實(shí)現(xiàn)思路及代碼,感興趣的你可不要錯(cuò)過(guò)了哈,希望本文可以幫助到你啊
    2013-02-02
  • JS中類(lèi)的靜態(tài)方法,靜態(tài)變量,實(shí)例方法,實(shí)例變量區(qū)別與用法實(shí)例分析

    JS中類(lèi)的靜態(tài)方法,靜態(tài)變量,實(shí)例方法,實(shí)例變量區(qū)別與用法實(shí)例分析

    這篇文章主要介紹了JS中類(lèi)的靜態(tài)方法,靜態(tài)變量,實(shí)例方法,實(shí)例變量區(qū)別與用法,結(jié)合實(shí)例形式詳細(xì)分析了JS中類(lèi)的靜態(tài)方法,靜態(tài)變量,實(shí)例方法,實(shí)例變量相關(guān)功能、使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • 淺談layui框架自帶分頁(yè)和表格重載的接口解析問(wèn)題

    淺談layui框架自帶分頁(yè)和表格重載的接口解析問(wèn)題

    今天小編就為大家分享一篇淺談layui框架自帶分頁(yè)和表格重載的接口解析問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-09-09
  • js+html5實(shí)現(xiàn)可在手機(jī)上玩的拼圖游戲

    js+html5實(shí)現(xiàn)可在手機(jī)上玩的拼圖游戲

    這篇文章主要介紹了js+html5實(shí)現(xiàn)可在手機(jī)上玩的拼圖游戲,涉及javascript結(jié)合html5進(jìn)行圖形操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • javascript自動(dòng)切換焦點(diǎn)控制效果完整實(shí)例

    javascript自動(dòng)切換焦點(diǎn)控制效果完整實(shí)例

    這篇文章主要介紹了javascript自動(dòng)切換焦點(diǎn)控制效果的方法,結(jié)合完整實(shí)例形式分析了JavaScript響應(yīng)鍵盤(pán)按鍵控制表單輸入框的焦點(diǎn)切換功能,需要的朋友可以參考下
    2016-02-02
  • JavaScript實(shí)現(xiàn)輪播圖特效

    JavaScript實(shí)現(xiàn)輪播圖特效

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)輪播圖特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 整理一些最近經(jīng)常遇到的前端面試題

    整理一些最近經(jīng)常遇到的前端面試題

    這篇文章主要給大家整理了一些在面試的時(shí)候經(jīng)常遇到的前端面試題,本文總結(jié)的這三十道面試題都是一些最近碰到的一些較為有用的前端題目,相信會(huì)對(duì)大家面試具有一定的參考價(jià)值,需要的朋友可以參考學(xué)習(xí),下面來(lái)一起看看吧。
    2017-04-04

最新評(píng)論

龙山县| 旺苍县| 垣曲县| 若尔盖县| 湟中县| 许昌市| 科技| 马尔康县| 肇源县| 秭归县| 普格县| 嘉峪关市| 庆阳市| 交城县| 沭阳县| 鄂托克旗| 江达县| 霍城县| 麦盖提县| 南乐县| 凤翔县| 织金县| 自贡市| 昌吉市| 茌平县| 神池县| 逊克县| 武山县| 高唐县| 竹北市| 宁蒗| 山东省| 阿拉尔市| 安泽县| 铜鼓县| 白玉县| 洛南县| 富阳市| 肇源县| 静安区| 奉新县|