Scrapy爬虫任务结束后发送带附件的电子邮件

113 阅读3分钟
  1. 在使用Scrapy进行爬虫项目时,我们需要定期检查网站的死链和缺失页面。我们创建了管道以将相关抓取信息写入文本文件,但遇到以下问题:
  • 无法在爬虫运行结束后发送电子邮件,并附上已创建的文件。
  • Scrapy具有内置的电子邮件功能,但难以理解如何合理地将所有内容整合在一起。

2、解决方案

创建电子邮件发送器扩展

为了解决上述问题,我们建议创建一个单独的电子邮件发送器扩展。扩展是Scrapy中用于自定义功能和行为的可重用组件。要创建电子邮件发送器扩展,我们需要完成以下步骤:

  1. 创建邮件发送器类: 在此类中,我们需要定义以下方法和属性:

    • __init__(self, recipients, mail, crawler):此方法用于初始化电子邮件发送器,其中recipients是收件人列表,mail是邮件发送器对象,crawler是当前的爬虫。
    • from_crawler(cls, crawler):这是一个类方法,用于从爬虫创建电子邮件发送器实例。
    • spider_closed(self, spider):当爬虫关闭时调用此方法。
    • item_scraped(self, item, response, spider):当爬虫抓取到一个项目时调用此方法。
    • spider_error(self, failure, response, spider):当爬虫遇到错误时调用此方法。
    • item_dropped(self, item, response, spider):当爬虫丢弃一个项目时调用此方法。
  2. 在设置中配置电子邮件发送器扩展: 在Scrapy设置中添加以下内容:

    • EXTENSIONS = {'your.mailer': 80}:这是一项扩展,用于指定电子邮件发送器扩展。
    • STATUSMAILER_RECIPIENTS = ["who should get mail"]:这是一个设置,用于指定电子邮件收件人列表。
    • MAIL_HOST = '***':这是一个设置,用于指定邮件服务器主机。
    • MAIL_PORT = ***:这是一个设置,用于指定邮件服务器端口。
    • MAIL_USER = '***':这是一个设置,用于指定邮件服务器用户名。
    • MAIL_PASS = '***':这是一个设置,用于指定邮件服务器密码。

实现电子邮件发送器管道

如果想在管道中实现电子邮件发送功能,也可以按照以下步骤操作:

  1. 创建电子邮件发送器管道: 在此管道中,我们需要定义以下方法和属性:

    • __init__(self):此方法用于初始化电子邮件发送器管道。
    • process_item(self, item, spider):当一个项目被抓取时调用此方法。
    • spider_closed(self, spider):当爬虫关闭时调用此方法。
  2. 在设置中配置电子邮件发送器管道: 在Scrapy设置中添加以下内容:

    • ITEM_PIPELINES = {'your.mailer': 80}:这是一项管道,用于指定电子邮件发送器管道。

代码示例

这是一个电子邮件发送器扩展的示例代码:

import scrapy
from scrapy.mail import MailSender

class MailSenderExtension(scrapy.extensions.Extension):

    def __init__(self, recipients, mail, crawler):
        self.recipients = recipients
        self.mail = mail
        self.crawler = crawler        

    @classmethod
    def from_crawler(cls, crawler):
        recipients = crawler.settings.getlist('STATUSMAILER_RECIPIENTS')
        if not recipients:
            raise NotConfigured

        mail = MailSender.from_settings(crawler.settings)
        instance = cls(recipients, mail, crawler)

        crawler.signals.connect(instance.item_scraped, signal=signals.item_scraped)
        crawler.signals.connect(instance.spider_error, signal=signals.spider_error)
        crawler.signals.connect(instance.spider_closed, signal=signals.spider_closed)
        crawler.signals.connect(instance.item_dropped, signal=signals.item_dropped)

        return instance

    def spider_closed(self, spider):
        self.mail.send(to=self.recipients, subject="Scrapy report", body="Finished crawling", attachs=[])

    def item_scraped(self, item, response, spider):
        pass

    def spider_error(self, failure, response, spider):
        pass

    def item_dropped(self, item, response, spider):
        pass

这个电子邮件发送器扩展的实现可以满足您的需求。