作为数据分析师,我通常会收到诸如“您可以每周向我发送此报告吗?”或“您是否可以每月通过电子邮件向我发送此数据?”这样的请求。发送报告很容易,但是如果您每周必须做同样的事情,那将很烦人。这就是为什么您应该学习如何使用Python发送电子邮件/报告以及在服务器上安排脚本的原因。
在本文上,我将向您展示如何从google BigQuery提取数据并将其作为报告发送。如果您只想知道如何使用Python发送电子邮件,则可以跳到“ 电子邮件”部分。
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.Application import MIMEApplication from datetime import datetime from os import path, remove import configparser import pandas as pd import shutil
email-with-python1.py
和往常一样,我们必须先导入库,然后再进入编码部分。我们将使用SMTP协议客户端发送电子邮件。ConfigParser用于读取存储SQL查询的配置文件。我将在下一部分中详细解释。
首先,您必须创建一个配置文件来存储所有SQL查询。用SQL查询分隔python脚本是一个好习惯,特别是当您的SQL查询很长(超过20行)时。这样,长时间的SQL查询不会使您的主脚本混乱。
配置文件示例
[report1] filename : Report1 dialect : standard query : SELECT * FROM table1 [report2] filename : Report2 dialect : standard query : SELECT * FROM table2 [report3] filename : Report3 dialect : standard query : SELECT * FROM table3
email-with-python.conf
[ report1 ]是您的sub-confiq。filename,dialect并且query是子配置的属性。
您可以使用以下代码读取配置文件。
FOLDER = path.dirname(path.realpath(__file__)) CONFIG_FILE = path.join(FOLDER, "query_detail.conf") config = configparser.RawConfigParser() config.read(CONFIG_FILE)
email-with-python2.py
编写函数以读取子配置的属性
def bigquery_to_csv(sub_conf): """ Output a csv file by reading query in config file Arguments: sub_conf {String} -- [Sub Confiq name in the confiq file] """ query = config.get(sub_conf, 'query') filename = config.get(sub_conf, 'filename') dialect = config.get(sub_conf, 'dialect') table = pd.read_gbq(query, project_id="yourProjectID", dialect=dialect, private_key="credential.json") filename = filename + current_date.strftime("%Y%m%d") + ".csv" filelist.append(filename) table.to_csv(filename)
email-with-python3.py
此自定义功能将读取您传入的子配置文件的属性,并输出CSV文件。
yourProjectID将是您的BigQuery项目ID,而credential.json将是您的BigQuery凭据JSON文件。如果您希望使用Web Auth登录,可以将其删除。
current_date = datetime.now() filelist = [] # Read all the sub confiq and output csv files sub_conf_list = config.sections() for sub_conf in sub_conf_list: bigquery_to_csv(sub_conf) print("Reports are extracted successfully!")
现在,您只需要循环就可以提取您在配置文件中定义的所有文件。config.sections()将在您的配置文件中返回一个子配置文件列表。
定义您的电子邮件内容
msg = MIMEMultipart() fromaddr = 'yourEmail@outlook.com' msg['From'] = fromaddr msg["To"] = "sender1@outlook.com,sender2@outlook.com" msg["Cc"] = "yourEmail@outlook.com" msg['Subject'] = "Report" htmlEmail = """ <p> Dear Sir/Madam, <br/><br/> Please find the attached Report below.<br/><br/> <br/></p> <p> Please contact XXX directly if you have any questions. <br/> Thank you! <br/><br/> Best Regards, <br/> XXX </p> <br/><br/> <font color="red">Please do not reply to this email as it is auto-generated. </font> """ for f in filelist: f = path.join(FOLDER, f) with open(f, "rb") as attached_file: part = MIMEApplication( attached_file.read(), Name=path.basename(f) ) # After the file is closed part['Content-Disposition'] = 'attachment; filename="%s"' % path.basename(f) msg.attach(part)
上面是您定义电子邮件属性的方式,例如发件人,收件人,抄送和主题。该htmlEmail会是你的电子邮件正文。您可以使用纯文本或html作为电子邮件正文。我更喜欢使用html,因为我可以进行更多的格式设置,如粗体,斜体和更改字体颜色。
同样,我们将使用循环附加所有文件。
发送邮件
msg.attach(MIMEText(htmlEmail, 'html')) server = smtplib.SMTP('smtp.office365.com', 587) server.starttls() server.login(fromaddr, "yourpassword") text = msg.as_string() server.sendmail(fromaddr, ['sender1@outlook.com','sender2@outlook.com'], text) server.quit() print("Email are sent successfully!")
出于演示目的,密码在脚本内进行了硬编码。这不是一个好习惯。您应该将密码保存在其他文件中,以提高安全性。
现在,您已经了解了如何使用Python发送带有附件的电子邮件。
您可以在我的[Github]中(https://github.com/chingjunetao/google-service-with-python/tree/master/email-with-python)查看完整的脚本。
翻译自:https://towardsdatascience.com/how-to-send-email-with-attachments-by-using-python-41a9d1a3860b