Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为了正确使用Scrapy发送电子邮件,我忘记了什么_Python_Python 2.7_Gmail_Scrapy - Fatal编程技术网

Python 为了正确使用Scrapy发送电子邮件,我忘记了什么

Python 为了正确使用Scrapy发送电子邮件,我忘记了什么,python,python-2.7,gmail,scrapy,Python,Python 2.7,Gmail,Scrapy,我想用Scrapy发送电子邮件 我阅读了官方网站,我发现我可以做到: 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.

我想用Scrapy发送电子邮件

我阅读了官方网站,我发现我可以做到:

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)
应用默认设置,因为正如您所看到的,我有自己的自定义选项,顺便说一句,我尝试使用默认设置,但结果相同,没有异常,但没有发送电子邮件


我希望你能帮我

你真的在使用代码引用的gmail地址吗?如果是这样的话,谷歌通常会在你第一次这么做的时候阻止你访问发送的邮件。我在使用PHPMailer时一直遇到这个问题。首先试着运行你的脚本,然后访问这个链接:它会给你一个来自谷歌的继续按钮。单击“继续”按钮,确认您正试图发送邮件。然后再次尝试运行脚本,看看是否有效。

您的代码会想到两件事。首先,是否要执行邮件程序代码,其次,应该填充
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")
下面是完整的工作文件,导入位于顶部附近,电子邮件代码位于spider类的末尾:

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\u 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

我用不上刮刮邮件。我用这个来代替:

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"

尝试将
smtptls=True
传递给邮件发件人。另外,请参阅:注意,该答案中的代码使用端口
587
——我没有尝试过,tho@elias我尝试添加
smtptls
,但仍然没有发送任何内容,另外,我不想复制该ansewr,因为它不是100%的scrapy框架。我想知道我在这个代码中的错误你有运行防病毒软件吗?在我添加了一个例外之前,我也有过类似的邮件发送挫折。我只是按照你说的做了,我仍然没有收到任何异常,但没有收到任何电子邮件。你是否也尝试过使用587端口而不是465端口?还有一些web主机会阻止这些端口,因此您无法通过它们发送邮件。我知道GoDaddy专门阻止发送邮件,所以如果你在GoDaddy托管计划中,你将无法发送这样的邮件。如果port/tls=true选项不起作用,请尝试与主机联系,看看它们是否允许您通过这些端口发送邮件。此外,我还很幸运地使用了第三方邮件公司SendGrid,它可以提供更好的电子邮件交付,而且您不必担心端口和其他托管废话。是的,我已经尝试了
587
端口,结果仍然相同。事实上,我不能使用第三方发送男性,这违反了公司的政策,了解,不幸的是,我不太了解刮擦,但如果它不抛出错误,将很难调试。也许在您等待更多答案时,请与您的主机联系,确保他们允许您通过这些端口发送邮件。正如我提到的,戈达迪不允许你这么做,所以如果这是问题所在,我也不会感到惊讶。
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"