实现过程
该程序通过qq等邮件服务器,通过获取邮箱的密钥来连接邮件服务器,实现发送邮件和从服务器获取收取的邮件。
代码
import email, sys
from imapclient import IMAPClient
from bs4 import BeautifulSoup
import imaplib
import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
class EmailAgent:
smtp_port = 587 #smtp端口
imap_port = 993
def __init__(
self, username, password, smtp_server, imap_server, smtp_port=587, imap_port=993
):
self.username = username
self.password = password
self.smtp_server = smtp_server
self.imap_server = imap_server
def send_email(self):
receivers = input("请输入目标邮箱(若为多个邮箱,用/分隔):").split("/")
subject = input("请输入标题:")
body = input("请输入内容:")
message = MIMEMultipart("related")
message["From"] = self.username
message["To"] = ",".join(receivers)
message["Subject"] = Header("Email Agent Test", "utf-8") # 标题
message_alternative = MIMEMultipart("alternative")
message.attach(message_alternative)
mail_msg = (
'<p>Test 李君!</p><p>您好,这是相关问题的图片</p><p><img src="cid:image1"></p>' + body
)
message_alternative.attach(MIMEText(mail_msg, "html", "utf-8"))
img_file = input("输入图片路径:")
if img_file != "":
try:
# 图片
mimeImage = MIMEImage(open(img_file, "rb").read())
mimeImage.add_header("Content-ID", "<image1>")
message.attach(mimeImage)
except:
print("图片路径错误!")
attachment_files = input("输入附件路径:")
if attachment_files != "":
try:
# 附件
mimeText = MIMEText(
open(attachment_files, "rb").read(), "base64", "utf-8"
)
mimeText["Content-Type"] = "application/octet-stream"
mimeText["Content-Disposition"] = (
'attachment; filename="' + attachment_files.split("\\")[-1] + '"'
)
message.attach(mimeText)
except:
print("附件路径错误!")
smtp = smtplib.SMTP(self.smtp_server)
smtp.login(self.username, self.password) # 登录
smtp.sendmail(self.username, receivers, message.as_string()) # 发送
smtp.quit()
print("邮件发送成功")
def download_emails(self):
server = IMAPClient(self.imap_server, ssl=True)
try:
server.login(self.username, self.password)
server.id_({"name": "IMAPClient", "version": "2.1.0"})
dictList = server.list_folders()
for a in dictList:
print(a)
info = server.select_folder("INBOX", readonly=True)
except server.Error:
print("登录失败")
sys.exit(1)
# 获取邮件列表
result = server.search()
print("邮件数量:%d" % len(result))
save_path = ""
while save_path == "":
save_path = input("输入存储的文件路径:")
for uid in result:
massageList = server.fetch(uid, ["BODY[]"])
mailBody = massageList[uid][b"BODY[]"]
try:
email_content = email.message_from_string(mailBody)
except TypeError:
email_content = email.message_from_string(
str(email.message_from_bytes(mailBody))
)
# 标题
subject = email.header.make_header(
email.header.decode_header(email_content["SUBJECT"])
)
# 发件人
mail_from = email.header.make_header(
email.header.decode_header(email_content["From"])
)
# 收件日期
envlope = (server.fetch(uid, ["ENVELOPE"]))[uid][b"ENVELOPE"]
dates = envlope.date
maintype = email_content.get_content_maintype()
maintype = email_content.get_content_maintype()
if maintype == "multipart":
for part in email_content.get_payload():
if part.get_content_maintype() == "text":
# 下载
mail_content = part.get_payload(decode=True).strip()
elif maintype == "text":
mail_content = (
email_content.get_payload(decode=True).strip().decode("utf-8")
)
try:
with open(save_path + f"/{subject}.txt", "w+", encoding="utf-8") as f:
f.write(f"From:{mail_from}" + "\n")
f.write(f"Subject:{subject}" + "\n")
f.write(f"Date:{dates}" + "\n")
f.write(f"正文内容:" + "\n")
f.write(
(
BeautifulSoup(mail_content, "html.parser")
.get_text()
.strip()
).replace("\n\n", "")
+ "\n"
)
attachment_file_name = email_content.get_filename()
if attachment_file_name:
file_name = decode_str(attachment_file_name)
data = email_content.walk().get_payload(decode=True)
# 保存附件文件
att_file = open(
os.path.join(f"/home/Code/Python/Test/IMAP/", file_name), "wb"
)
attachment_files.append(file_name)
att_file.write(data)
att_file.close()
print(f"附件 {file_name} 下载完成")
except:
print("存储路径错误!")
def main():
i = ""
while i is not "q":
option = input("选择功能(f:发送,d:下载邮件):")
ea = EmailAgent(
"354425203@qq.com", "cvsbbfutyhstcbgbg", "pop.qq.com", "smtp.qq.com"
)
if option == "f":
ea.send_email()
elif option == "d":
ea.download_emails()
i = input("退出输入q或quit:")
if __name__ == "__main__":
main()