天天看點

Scrapy使用MailSender發送郵件

1、配置郵箱賬号 163為例

settings.py

# 郵箱配置
MAIL_HOST = "smtp.163.com"
MAIL_FROM = "[email protected]"
MAIL_USER = "[email protected]"
MAIL_PASS = "xxx"   # 授權碼
MAIL_PORT = 25      

2、發送郵件的代碼

# -*- coding: utf-8 -*-

import scrapy
from scrapy import cmdline
from scrapy.mail import MailSender


class SendEmailSpider(scrapy.Spider):
    name = 'send_email'

    start_urls = ['https://www.baidu.com/']

    def parse(self, response):
        # 方式一:讀取配置檔案中的配置
        # debug參數為True 不會發送郵件,僅僅列印日志
        mailer = MailSender(
            smtphost=self.settings["MAIL_HOST"],
            mailfrom=self.settings["MAIL_FROM"],
            smtpuser=self.settings["MAIL_USER"],
            smtppass=self.settings["MAIL_PASS"],
            smtpport=self.settings["MAIL_PORT"]
        )
        
        # 方式二:直接傳入settings 對象
        mailer = MailSender.from_settings(self.settings)
        
        # 發送郵件
        return mailer.send(
            to=["[email protected]"],
            subject="這是郵件标題",
            body="這是郵件内容"
        )


if __name__ == '__main__':
    cmdline.execute("scrapy crawl send_email".split())
      

問題

1、問題一

以上代碼如果不加

return

, 可以正常發送郵件

mailer.send(
    to=["[email protected]"],
    subject="這是郵件标題",
    body="這是郵件内容"
)      

不過會報錯

builtins.AttributeError: 'NoneType' object has no attribute 'bio_read'      

2、問題二

如果按照文檔的寫法直接不傳參數執行個體化

MailSender

mailer = MailSender()      

會報錯

Unable to send mail: To=['[email protected]'] Cc=[] Subject="這是郵件标題" Attachs=0- 
Connection was refused by other side: 61: Connection refused.      

原因是

MailSender

的執行個體化參數是固定的預設值,并沒有讀取settings.py檔案中設定的值,坑~~

構造函數源碼如下

class MailSender(object):

    def __init__(self, smtphost='localhost', mailfrom='scrapy@localhost',
            smtpuser=None, smtppass=None, smtpport=25, 
            smtptls=False, smtpssl=False, debug=False):
        self.smtphost = smtphost
        self.smtpport = smtpport
        self.smtpuser = _to_bytes_or_none(smtpuser)
        self.smtppass = _to_bytes_or_none(smtppass)
        self.smtptls = smtptls
        self.smtpssl = smtpssl
        self.mailfrom = mailfrom
        self.debug = debug
      

如果采用此方式執行個體化

MailSender

 需要采用方式一手動讀取配置

吐槽:搞不懂scrapy作者為啥要設定完全沒有用的預設值, 也不報錯,坑了一波人

3、問題三

如果按照文檔的寫法

mailer = MailSender.from_settings(settings)      

直接就會報錯,都沒有定義

NameError: name 'settings' is not defined      

我的第一感覺是把項目的

settings.py

 導入傳進去

import settings

mailer = MailSender.from_settings(settings)      

然後又報錯了

TypeError: 'module' object is not subscriptable      

檢視文檔參數說明才知道要傳一個

settings

 對象

settings (scrapy.settings.Settings object)      

是以需要按照方式二的形式,才能正确擷取setting對象

吐槽:動态語言的函數定義并沒有嚴格要求參數類型,沒有把具體的參數類型寫清楚,不看文檔完全不知道傳什麼參數

參考

  1. https://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/email.html