写了一个每天定时发送邮件的爬虫

106 阅读2分钟

结合上一章的掘金首页词云图,把生成的词云图进行邮件发送到指定邮箱

# 写了一个node+python的爬虫小工具玩玩

这里可以使用自己的两个邮箱(一个发一个接收)

最终效果图:

63fc51c8f431fed4f93beca24223157.jpg

首先发送的邮件要支持smtp(具体方法可以自己百度,这里不过多解释)

安装邮件发送服务和定时任务依赖

npm install nodemailer cron
async function sendEmailWithImage (attachmentPath, recipientEmail) {
  console.log("🚀 ~ sendEmailWithImage ~ attachmentPath:", attachmentPath)
  // 创建一个SMTP客户端配置
  let transporter = nodemailer.createTransport({
    host: 'smtp.qq.com', // 您的SMTP服务提供商的主机名
    port: 587, // SMTP端口
    secure: false, // 如果端口为465,则为true,其他端口通常为false
    auth: {
      user: '你的邮箱@qq.com', // 发送者邮箱
      pass: '授权码' // 邮箱密码或应用专用密码
    }
  });
  // 生成邮件的 HTML 内容,包含所有图片
  let htmlContent = '<h3>这里是每日词云图推荐频道的推荐:</h3>';
  for (const [index, imgPath] of attachmentPath.entries()) {
    const filename = path.basename(imgPath);
    htmlContent += `<div><strong>${filename.split('.png')[0]}:</strong><br /><img src="cid:image${index}" style="max-width: 100%;" /></div><br />`;
  }
  // 设置邮件内容
  let mailOptions = {
    from: '"掘金每日词云图频道" <发件人@qq.com>', // 发件人
    to: recipientEmail, // 收件人
    subject: '掘金每日词云图', // 主题
    text: '这里是每日词云图推荐频道的推荐.', // 纯文本内容
    html: htmlContent, // HTML内容
    attachments: attachmentPath.map((imgPath, index) => ({
      filename: path.basename(imgPath),
      path: imgPath,
      cid: `image${index}` // Content ID,用于在HTML内容中引用图片
    }))
  };

  // 发送邮件
  let info = await transporter.sendMail(mailOptions);
  console.log('Message sent: %s', info.messageId);
}

export {
  sendEmailWithImage
}
/*
 * @Descripttion: 每日定时任务
 * @Author: lihk
 * @Date: 2024-03-16 10:49:43
 */
import { CronJob } from 'cron';
import fs from 'fs';
import path from 'path';
import { sendEmailWithImage } from './src/email/index.js';
import { crawler } from './src/crawler/index.js';
// 遍历wordcloud文件夹获取所有图片路径
function getWordCloudImages (directory) {
  return new Promise((resolve, reject) => {
    fs.readdir(directory, (err, files) => {
      if (err) {
        reject(err);
        return;
      }
      // 过滤出图片文件并转换为完整路径
      const imagePaths = files
        .filter((file) => /\.(png|jpe?g|gif)$/i.test(file))
        .map((file) => path.join(directory, file));
      resolve(imagePaths);
    });
  });
}

// 设置定时任务
const job = new CronJob('0 9 * * *', async function () {
  console.log('开始执行定时任务');

  // 这里调用您的爬虫脚本和生成图片的逻辑
  await crawler()
  // 遍历wordclound文件夹,拿到所有的词云图
  try {
    // wordcloud文件夹路径,根据实际情况修改
    const wordCloudDirectory = './wordcloud';
    const imagePaths = await getWordCloudImages(wordCloudDirectory);
    console.log("🚀 ~ job ~ imagePaths:", imagePaths)

    // 发送邮件
    // await sendEmailWithImage(imagePaths, 'lihk180542@gmail.com');
  } catch (error) {
    console.error('定时任务执行出错:', error);
  }

  // 发送邮件
  await sendEmailWithImage(imagePath, 'lihk180542@gmail.com');

  console.log('定时任务执行完毕');
}, null, true, 'Asia/Shanghai'); // 设置时区

// 启动定时任务
job.start();
// 测试代码
const main = async () => {
  await crawler()
  const wordCloudDirectory = './wordcloud';
  const imagePaths = await getWordCloudImages(wordCloudDirectory);
  console.log("🚀 ~ job ~ imagePaths:", imagePaths)
  // 发送邮件
  await sendEmailWithImage(imagePaths, '收件人@gmail.com');
}
main()