【问题标题】:count number of emails sent using smtplib python计算使用 smtplib python 发送的电子邮件数量
【发布时间】:2020-07-25 08:41:10
【问题描述】:

我有一个基本的 Python 代码,它可以向 Google 表格列表中的地址发送电子邮件。

我想计算 Python 脚本向特定电子邮件地址发送电子邮件的次数。我试着研究它。我没有找到任何与之相关的东西。作为一个完整的初学者并没有帮助我取得太大的进步。

如果有人能指出一个特定的方向,那将是非常有帮助的。提前非常感谢。

下面是代码

import smtplib
import ssl
from email.mime.text import MIMEText  # New line
from email.utils import formataddr  # New line

# User configuration
sender_email = 'email ID'
sender_name = 'name'
password = "password"

receiver_emails = [RECEIVER_EMAIL_1, RECEIVER_EMAIL_2, RECEIVER_EMAIL_3]
receiver_names = [RECEIVER_NAME_1, RECEIVER_NAME_2, RECEIVER_NAME_3]

# Email text
email_body = '''
    This is a test email sent by Python. Isn't that cool?
'''

for receiver_email, receiver_name in zip(receiver_emails, receiver_names):
    print("Sending the email...")

    # Configurating user's info
    msg = MIMEText(email_body, 'plain')
    msg['To'] = formataddr((receiver_name, receiver_email))
    msg['From'] = formataddr((sender_name, sender_email))
    msg['Subject'] = 'Hello, my friend ' + receiver_name

    try:
        # Creating a SMTP session | use 587 with TLS, 465 SSL and 25
        server = smtplib.SMTP('smtp.gmail.com', 587)
        server.ehlo()
        # Encrypts the email
        context = ssl.create_default_context()
        server.starttls(context=context)
        # We log in into our Google account
        server.login(sender_email, password)
        # Sending email from sender, to receiver with the email body
        server.sendmail(sender_email, receiver_email, msg.as_string())
        print('Email sent!')

    except Exception as e:
        print(f'Oh no! Something bad happened!n {e}')

    finally:
        print('Closing the server...')
        server.quit()

【问题讨论】:

  • 你能分享你的代码吗?
  • 已更新代码
  • 你想统计每个地址(receiver_email)发送成功的次数吗?
  • 是的,没错。脚本成功发送到每个地址的电子邮件

标签: python python-3.x gmail-api google-sheets-api smtplib


【解决方案1】:

我建议您创建一个成功电子邮件列表,该列表将在每次迭代时填充,然后使用来自collections 模块的Counter,该模块接收一个可迭代对象并返回一个包含每个元素出现次数的对象在可迭代中。 你可以试试下面的代码:

from collections import Counter
import json

counter_file_path = "counter.json"
try:
    with open(counter_file_path, "r") as f:
        email_stats = json.load(f)
except FileNotFoundError as ex:
        email_stats = {}

successful_emails = []
for receiver_email, receiver_name in zip(receiver_emails, receiver_names):
    print("Sending the email...")

    # Configurating user's info
    msg = MIMEText(email_body, 'plain')
    msg['To'] = formataddr((receiver_name, receiver_email))
    msg['From'] = formataddr((sender_name, sender_email))
    msg['Subject'] = 'Hello, my friend ' + receiver_name

    try:
        # Creating a SMTP session | use 587 with TLS, 465 SSL and 25
        server = smtplib.SMTP('smtp.gmail.com', 587)
        server.ehlo()
        # Encrypts the email
        context = ssl.create_default_context()
        server.starttls(context=context)
        # We log in into our Google account
        server.login(sender_email, password)
        # Sending email from sender, to receiver with the email body
        server.sendmail(sender_email, receiver_email, msg.as_string())
        print('Email sent!')
        if receiver_email in email_stats:
            email_stats[receiver_email] += 1
        else:
            email_stats[receiver_email] = 1
    except Exception as e:
        print(f'Oh no! Something bad happened!n {e}')

    finally:
        print('Closing the server...')
        server.quit()

print(email_stats) # output - all occurrences for each email 
with open(counter_file_path, "w") as f:
     json.dump(email_stats, f)

【讨论】:

  • 非常感谢!我会试一试的。
  • 嗨,所以这起到了一定的作用。我想知道是否有办法计算发送到每个 ID 的成功电子邮件。例如:假设脚本向“abc@email.com”发送了两次电子邮件。所以它应该反映 2。然后它再次成功发送,所以计数应该增加到 3,依此类推。目前,每次迭代仅显示 1 个。另外,我想将计数保存到 Google 工作表中。如何将数字转换为可以轻松保存在 Google 表格中的字符串格式?
  • 您想计算脚本不同运行之间的出现次数吗? @SouravChatterjee
  • 是的。这就是我希望它计数的方式。
  • 好的,因此您应该将计数器结果保存到文件或数据库中,并在每次运行时更新它们。我更新了解决方案,将计数器结果保存到每次运行时都会更新的 json 文件。该文件将在每次运行开始时加载到email_stats 变量中,在运行期间更新,并在脚本完成时再次保存。
【解决方案2】:

您可以使用此代码将成功邮件计数存储/打印为 JSON 格式。

import smtplib
import SSL
import json
import os
from email.mime.text import MIMEText  # New line
from email.utils import formataddr  # New line

fileName = "sendMail_count.json"
# To store data into json file.
# It will create file in datetime format.
def store_data_to_file(jsonStr):
    jsonFile = open(fileName, "w")
    json.dump(jsonStr, jsonFile)
    print("data stored successfully")

# User configuration
sender_email = 'email ID'
sender_name = 'name'
password = "password"

receiver_emails = [RECEIVER_EMAIL_1, RECEIVER_EMAIL_2, RECEIVER_EMAIL_3]
receiver_names = [RECEIVER_NAME_1, RECEIVER_NAME_2, RECEIVER_NAME_3]

# To store the count of successful mail received by receiver with their respective email.
if not os.path.exists(fileName) or os.stat(fileName).st_size == 0:
    print("File is empty or not found")
    print("Creating a JSON file to store the data")
    jsonFile = open(fileName, "w+")
    print("a JSON file has been created with name: " + str(fileName))
    success_mail_count = {}
else:
    with open(fileName) as jsonFile:
        success_mail_count = json.load(jsonFile)
    print(success_mail_count)

# Email text
email_body = '''
    This is a test email sent by Python. Isn't that cool?
'''

for receiver_email, receiver_name in zip(receiver_emails, receiver_names):
    count = 0
    print("Sending the email to..." + receiver_email)

    # Configurating user's info
    msg = MIMEText(email_body, 'plain')
    msg['To'] = formataddr((receiver_name, receiver_email))
    msg['From'] = formataddr((sender_name, sender_email))
    msg['Subject'] = 'Hello, my friend ' + receiver_name

    try:
        # Creating a SMTP session | use 587 with TLS, 465 SSL and 25
        server = smtplib.SMTP('smtp.gmail.com', 587)
        server.ehlo()
        # Encrypts the email
        context = ssl.create_default_context()
        server.starttls(context=context)
        # We log in into our Google account
        server.login(sender_email, password)
        # Sending email from sender, to receiver with the email body
        server.sendmail(sender_email, receiver_email, msg.as_string())

        # Check if recevier is already present in the dict, 
        # then add 1 to its current count
        if receiver_email in success_mail_count:
            success_mail_count[receiver_email] = str(int(success_mail_count[receiver_email]) + 1)
        # If reciever isn't present in map then create new entry for receiver and 
        # Update the count with one for successfull mail sent.
        else:
            success_mail_count[receiver_email] = str(count + 1)

        print('Email sent!')

    except Exception as e:
        print(f'Oh no! Something bad happened!n {e}')

    finally:
        print('Closing the server...')
        server.quit()

print(success_mail_count)

store_data_to_file(success_mail_count)

运行此代码,它会在文件中创建数据,然后它会从文件本身读取数据。

【讨论】:

  • 嗨,所以这起到了一定的效果,类似于另一个答案。我想知道是否有办法计算发送到每个 ID 的成功电子邮件。例如:假设脚本向“abc@email.com”发送了两次电子邮件。所以它应该反映 2。然后它再次成功发送,所以计数应该增加到 3,依此类推。目前,每次迭代仅显示 1 个。另外,我想将计数保存到 Google 工作表中。如何将数字转换为可以轻松保存在 Google 表格中的字符串格式。
  • 您好,我建议您将数据存入文件以便进一步计算,我已经修改了我的代码。
  • 输出将如下所示:{'RECEIVER_EMAIL_1': '5', 'RECEIVER_EMAIL_2': '5', 'RECEIVER_EMAIL_3': '5'}
  • 嗨,这只是将最后一个电子邮件地址保存在 JSON 文件中。此外,它不会随着脚本的每次运行而增加。我尝试将代码的最后一部分,即print(success_mail_count) # if you want to store data into file you can use this funtion store_data_to_file(success_mail_count) 转换为finally: 块。在那里,它只是覆盖了每个电子邮件地址,而不是用新的电子邮件 ID 附加一个新行。而且,这里没有增加。
  • 我已经更新了代码,请检查一次。我在本地尝试了 4 到 5 次,它在文件中创建数据并更新文件中的计数。
猜你喜欢
  • 2021-04-26
  • 1970-01-01
  • 2014-01-31
  • 2023-02-11
  • 2011-02-12
  • 2018-12-09
  • 2015-09-07
  • 2017-09-20
  • 2018-11-19
相关资源
最近更新 更多