Python 实现收发邮件,并通过命令将邮件内容上传到BBS
1.使用POP3服务读取邮件内容
# -*- coding: utf-8 -*-
# 我将所有的功能写成一个个内,以便实现全自动的效果
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
import poplib
import os
# 输入邮件地址, 口令和POP3服务器地址:
email = '你的邮箱地址'#[email protected]等等
password = '邮箱密码'#163和qq不是邮箱的登录密码而是服务密码,在设置里找一下
pop3_server = '邮箱服务器名称'#pop.qq.com等等
#全局变量,用于储存邮件标题和发件人,为后面上传到BBS以及发送邮件有关
title = ''
from_name = ''
from_addr = ''
#判断邮件内容是否是UTF-8编码
def guess_charset(msg):
charset = msg.get_charset()
if charset is None:
content_type = msg.get('Content-Type', '').lower()
pos = content_type.find('charset=')
if pos >= 0:
charset = content_type[pos + 8:].strip()
return charset
#解码 str--->文字
def decode_str(s):
value, charset = decode_header(s)[0]
if charset:
value = value.decode(charset)
return value
#indent 用于缩进
def print_info(msg, indent=0):
global title
global from_name
global from_addr
if indent == 0:
for header in ['Subject', 'From', 'To',]:
value = msg.get(header, '')
if value:
if header=='Subject':
value = decode_str(value)
title = value
else:
hdr, addr = parseaddr(value)
name = decode_str(hdr)
value = u'%s <%s>' % (name, addr)
if header == 'From':
from_name = name
from_addr = addr
print('%s%s: %s' % (' ' * indent, header, value))
if (msg.is_multipart()):
parts = msg.get_payload()
for n, part in enumerate(parts):
#print('%spart %s' % (' ' * indent, n))
print('%s--------------------' % (' ' * indent))
print_info(part, indent + 1)
else:
content_type = msg.get_content_type()
if content_type=='text/plain' :
content = msg.get_payload(decode=True)
charset = guess_charset(msg)
if charset:
content = content.decode(charset)
print('%sText: \n%s' % (' ' * indent, content))
#把邮件的内容写入到一个txt文件中
f = open("./"+ title + ".txt", 'a+')
f.write(content)
f.write("\n" +"From: " + from_addr)
f.close()
return title,from_name,from_addr
class reciveEmail:
def __init__(self):
print("start to recive the latest email")
def pop(self):
global title
global from_name
global from_addr
# 连接到POP3服务器:
server = poplib.POP3(pop3_server)
# 可以打开或关闭调试信息:
#server.set_debuglevel(1)
# 身份认证:
server.user(email)
server.pass_(password)
# stat()返回邮件数量和占用空间:
print('Messages: %s. Size: %s' % server.stat())
# list()返回所有邮件的编号:
resp, mails, octets = server.list()
# 可以查看返回的列表类似[b'1 82923', b'2 2184', ...]
print(mails)
# 获取最新一封邮件, 注意索引号从1开始:
index = len(mails)
resp, lines, octets = server.retr(index)
# lines存储了邮件的原始文本的每一行,
# 可以获得整个邮件的原始文本:
msg_content = b'\r\n'.join(lines).decode('utf-8')
# 稍后解析出邮件:
msg = Parser().parsestr(msg_content)
title,from_name,from_addr= print_info(msg)
return title,from_name,from_addr
# 可以根据邮件索引号直接从服务器删除邮件:
# server.dele(index)
# 关闭连接:
server.quit()
#if __name__ == '__main__':
# popmail = reciveEmail()
# popmail.pop()# 测试一下
2.将读取到的邮件的内容上传到BBS上
# -*- coding: utf-8 -*-
# 这里是我自己搭建的BBS,使用Nodebb论坛,大家可以自己去网上了解一下
# 实现自动发帖还需要在BBS里安装一个插件 nodebb-plugin-write-api
import os
import subprocess
import re
class newTopic:
def __init__(self):
print("Ready to create a new topic....")
def post(self,title,cid):
self.title = title
self.cid = cid
f = open("./" + self.title + ".txt","a+")
f.seek(0)#将文件指针重置到开头,否则讲读不到内容
lines = f.read()
cmd = 'curl -X POST -H "Authorization: Bearer ........" \
--data "title=' + self.title + '&content=' + lines + '&cid='+ self.cid + '" \
http://localhost:4567/api/v2/topics'
# 上面的....表示的是在插件页面生成的用户信息编码,大家可以自己尝试一下
# 执行命令行并获取结果
pipe = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout
result = pipe.read()
result = str(result)
#找到tid uid cid等信息
tucm_id = re.findall(r'"tid":\d+,"uid":\d+,"cid":\d+,"mainPid":\d+', result)
#列表转换为字符串
tucm_id = ",".join(tucm_id)
f.write('\n' + tucm_id)
f.close()
print("New topic has been pushed successfully....")
#if __name__ == '__main__':
# topic = newTopic()
# topic.post('test2','1') #这里测试的是邮件名为test2,发在tid为1的板块下
3.使用smtp服务将发送成功的消息通过邮件发送给刚才的发件人
# -*- coding: utf-8 -*-
#转发tid uid cid等信息
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
#解码
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
class resendEmail():
def __init__(self):
print("start to send id message to user.....")
def resend(self,to_name,to_addr,title):
# 发件信息
self.from_addr = '发件邮箱'#可以查看第一篇pop收件
self.from_name = '显示的发件人名称'
self.password = '邮箱密码'
self.smtp_server = '邮箱服务器'
self.title = title
self.to_addr = to_addr
self.to_name = to_name
f = open("./" + self.title + ".txt","r")
lines = f.readlines()# 逐行读取
#邮件内容
Text = ''.join(lines[:-1])
msg = MIMEText('Your email has been pushed on bbs successfully!\n' , 'plain', 'utf-8')
msg['From'] = _format_addr('%s <%s>' % (self.from_name,self.from_addr))#发件人(你自己)
msg['To'] = _format_addr(self.to_name + '<%s>' % self.to_addr)#收件人
msg['Subject'] = Header('your email has released on bbs with ' + lines[-1], 'utf-8').encode()#邮件标题
#smtp服务启动到关闭
server = smtplib.SMTP(self.smtp_server, 25)
server.set_debuglevel(1)
server.login(self.from_name, self.password)
server.sendmail(self.from_addr, [self.to_addr], msg.as_string())
server.quit()
f.close()
#if __name__ == '__main__':
# idd = resendEmail()
# idd.resend('xx','[email protected]','test2')#测试发给xx,他的邮箱是[email protected],之前发来的邮件名字是test2
4.调用之前写好的所有功能
#这是前几个文件的名字,你可以自己改动
import pop_email
import new_topic
import resend_email
new_test = pop_email.reciveEmail()
title,from_name,from_addr= new_test.pop()#读邮件到文件中
new_topic = new_topic.newTopic()
new_topic.post(title,'1')#发帖
resend = resend_email.resendEmail()
resend.resend(from_name,from_addr,title)#将发帖成功的消息通过邮件通知他
5.使用imap服务检测是否有新邮件。每当有新邮件就会自动实现读取,发帖,回信的操作
import imaplib
import re,os
def LoginMail(hostname, user, password):
r = imaplib.IMAP4(hostname)
r.login(user, password)
x,y = r.status('INBOX', '(MESSAGES UNSEEN)')#获取邮箱的状态,y是邮箱未读邮件的数量
import chardet # 检测编码格式
encode_type = chardet.detect(y[0])
y[0] = y[0].decode(encode_type['encoding'])
unseen = re.findall(r'UNSEEN \d+',y[0])
num = re.findall(r'\d+',unseen[0])
num = ''.join(num) # 列表转字符串
#print(type(int(num)))
if num > '0':
#print("There are %s mails unread." % num)
os.system("python test_mail_topic.py")#调用第4步写好的脚本
else:
print("No mail unread")
if __name__ == '__main__':
while(True):
LoginMail('邮箱服务器', '邮箱', '邮箱密码')#可以一直挂在后台