【问题标题】:What did I forget in order to correctly send an email using Scrapy为了使用 Scrapy 正确发送电子邮件,我忘记了什么
【发布时间】:2015-05-22 16:14:53
【问题描述】:

我想用 Scrapy 发送邮件

看了throw官网,发现可以这样做:

from scrapy.mail import MailSender
        from scrapy.utils.project import get_project_settings
        settings = get_project_settings()
        mailer = MailSender(mailfrom ="Something@gmail.com", smtphost="smtp.gmail.com", smtpport=465, smtppass ="MySecretPassword")
        mailer.send(to=["AnotherMail@gmail.com"], subject="Some subject", body="Some body")

代码没有抛出任何异常,但是没有邮件被发送。

我错过了什么?

注1:

我需要使用 Scrapy 框架,而不是纯 Python

注2:

我不想使用mailer = MailSender.from_settings(settings) 应用默认设置,因为如您所见,我有我的自定义选项,并且我尝试使用默认设置,但结果相同,没有例外,但没有电子邮件已发送。

希望你能帮助我

【问题讨论】:

  • 尝试将smtptls=True 传递给MailSender。另请参阅:stackoverflow.com/questions/11411033/…
  • 请注意,该答案中的代码使用端口587——我还没有尝试过。
  • @elias 我尝试添加smtptls,但仍然没有发送任何内容,另外,我不想复制那个ansewr,因为它不是100% 的scrapy 框架。我想知道我在这段代码中的错误
  • 你有运行杀毒软件吗?在添加例外之前,我在发送电子邮件时遇到过类似的挫败感。

标签: python python-2.7 gmail scrapy


【解决方案1】:

您的代码想到了两件事。首先,是否正在执行邮件程序代码,其次,应填充smtpuser 参数。

这是使用 Scrapy 通过 Gmail 发送电子邮件的工作代码。这个答案有 4 个部分:电子邮件代码、完整示例、日志记录和 Gmail 配置。提供了完整的示例,因为需要协调一些事情才能使其工作。

电子邮件代码

要让 Scrapy 发送电子邮件,您可以在您的 Spider 类中添加以下内容(完整示例在下一节中)。这些示例让 Scrapy 在抓取完成后发送电子邮件。

有两段代码要添加,第一段用于导入模块,第二段用于发送电子邮件。

导入模块:

from scrapy import signals
from scrapy.mail import MailSender

在您的 Spider 类定义中:

class MySpider(Spider):

    <SPIDER CODE>

    @classmethod
    def from_crawler(cls, crawler):
        spider = cls()
        crawler.signals.connect(spider.spider_closed, signals.spider_closed)
        return spider

    def spider_closed(self, spider):
        mailer = MailSender(mailfrom="Something@gmail.com",smtphost="smtp.gmail.com",smtpport=587,smtpuser="Something@gmail.com",smtppass="MySecretPassword")
        return mailer.send(to=["AnotherMail@gmail.com"],subject="Some subject",body="Some body")

完整示例

综上所述,本示例使用位于以下位置的 dirbot 示例:

https://github.com/scrapy/dirbot

只需要编辑一个文件:

./dirbot/spiders/dmoz.py

这是整个工作文件,顶部附近的导入和蜘蛛类末尾的电子邮件代码:

from scrapy.spider import Spider
from scrapy.selector import Selector

from dirbot.items import Website

from scrapy import signals
from scrapy.mail import MailSender

class DmozSpider(Spider):
    name = "dmoz"
    allowed_domains = ["dmoz.org"]
    start_urls = [
        "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/",
    ]

    def parse(self, response):
        """
        The lines below is a spider contract. For more info see:
        http://doc.scrapy.org/en/latest/topics/contracts.html

        @url http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/
        @scrapes name
        """
        sel = Selector(response)
        sites = sel.xpath('//ul[@class="directory-url"]/li')
        items = []

        for site in sites:
            item = Website()
            item['name'] = site.xpath('a/text()').extract()
            item['url'] = site.xpath('a/@href').extract()
            item['description'] = site.xpath('text()').re('-\s[^\n]*\\r')
            items.append(item)

        return items

    @classmethod
    def from_crawler(cls, crawler):
        spider = cls()
        crawler.signals.connect(spider.spider_closed, signals.spider_closed)
        return spider

    def spider_closed(self, spider):
        mailer = MailSender(mailfrom="Something@gmail.com",smtphost="smtp.gmail.com",smtpport=587,smtpuser="Something@gmail.com",smtppass="MySecretPassword")
        return mailer.send(to=["AnotherMail@gmail.com"],subject="Some subject",body="Some body")

更新此文件后,从项目目录运行标准抓取命令以抓取并发送电子邮件:

$ scrapy crawl dmoz

记录

通过在spider_closed 方法中返回mailer.send 方法的输出,Scrapy 会自动将结果添加到它的日志中。以下是成功和失败的例子:

成功日志消息:

2015-03-22 23:24:30-0000 [scrapy] INFO: Mail sent OK: To=['AnotherMail@gmail.com'] Cc=None Subject="Some subject" Attachs=0

错误日志消息 - 无法连接:

2015-03-22 23:39:45-0000 [scrapy] ERROR: Unable to send mail: To=['AnotherMail@gmail.com'] Cc=None Subject="Some subject" Attachs=0- Unable to connect to server.

错误日志消息 - 身份验证失败:

2015-03-22 23:38:29-0000 [scrapy] ERROR: Unable to send mail: To=['AnotherMail@gmail.com'] Cc=None Subject="Some subject" Attachs=0- 535 5.7.8 Username and Password not accepted. Learn more at 5.7.8 http://support.google.com/mail/bin/answer.py?answer=14257 sb4sm6116233pbb.5 - gsmtp

Gmail 配置

要将 Gmail 配置为以这种方式接受电子邮件,您需要启用“访问安全性较低的应用程序”,您可以在登录帐户后通过以下 URL 进行操作:

https://www.google.com/settings/security/lesssecureapps

【讨论】:

    【解决方案2】:

    您实际上使用的是您的代码所引用的 gmail 地址吗?如果是这样,谷歌通常会在您执行此操作时第一次阻止访问外发邮件。我在使用 PHPMailer 时一直遇到这个问题。首先尝试运行您的脚本,然后访问此链接:https://accounts.google.com/displayunlockcaptcha,这将为您提供来自 google 的继续按钮。单击该继续按钮,该按钮将验证您是否正在尝试发送邮件。然后尝试再次运行您的脚本,看看是否有效。

    【讨论】:

    • 我只是按照你说的做了,还是没有收到任何异常,但是没有收到任何邮件
    • 您是否也尝试过使用端口 587 而不是 465?此外,一些网络主机会阻止这些端口,因此您无法通过它们发送邮件。我知道 GoDaddy 专门阻止外发邮件,所以如果您使用的是 godaddy 托管计划,您将无法发送这样的邮件。如果 port / tls=true 选项不起作用,请尝试联系您的主机并查看它们是否允许您通过这些端口发送邮件。此外,我使用第三方邮件公司 SendGrid 非常幸运,它可以提供更好的电子邮件传送能力,而且您不必担心端口和其他托管废话。 sendgrid.com
    • 是的,我已经尝试了587 端口,结果仍然相同。其实我不能用第三方送男,违反公司政策
    • 明白,不幸的是我对scrapy知之甚少,但如果它不抛出错误,将很难调试。也许在您等待更多答案时,请联系您的主机并确保他们允许您通过这些端口发送邮件。正如我所提到的,godaddy 不允许你这样做,所以如果这是问题所在,我不会感到惊讶。
    【解决方案3】:

    垃圾邮件对我不起作用。我改用这个:

    def send_mail(self, message, title):
        print "Sending mail..........."
        import smtplib
        from email.MIMEMultipart import MIMEMultipart
        from email.MIMEText import MIMEText
        gmailUser = 'mail_you_send_from@gmail.com'
        gmailPassword = 'password'
        recipient = 'mail_to_send_to'
    
        msg = MIMEMultipart()
        msg['From'] = gmailUser
        msg['To'] = recipient
        msg['Subject'] = title
        msg.attach(MIMEText(message))
    
        mailServer = smtplib.SMTP('smtp.gmail.com', 587)
        mailServer.ehlo()
        mailServer.starttls()
        mailServer.ehlo()
        mailServer.login(gmailUser, gmailPassword)
        mailServer.sendmail(gmailUser, recipient, msg.as_string())
        mailServer.close()
        print "Mail sent"
    

    【讨论】:

      猜你喜欢
      • 2020-03-26
      • 2016-08-31
      • 2011-02-19
      • 2011-07-19
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 2015-06-22
      • 2013-06-13
      相关资源
      最近更新 更多