室友太懒,晚上电脑开热点经常忘记设置电脑自动关机,可苦了我这个勤奋的孩子......
思路:python先登录邮箱,利用邮箱发送指令,每隔一段时间程序检测是否有关机指发送过来,然后把命令转成cmd命令。同时反馈指令是否发送成功。
这里使用的是QQ邮箱,想要用程序登录邮箱需要开通IMAP/SMTP服务。在我的邮箱->邮箱设置->账户->POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务
设置成功后会有密码返回,保存密码,我们后面会用到
发送邮件需要构建下面的信息:
s_mes = { 'From': '你的[email protected]', # 你的qq邮箱 'password': '', # 我们刚刚获得的密码 'To': '需要发送的邮箱@qq.com', # 接收的邮箱 'Subject': '这是主题', # 发送的主题,可以不填 'message': "关机 3600", # 发送的信息 }
发送邮箱代码如下:
def send_email(s_mes):
my_sender = s_mes["From"] # 发送人的账号
my_pass = s_mes["password"] # 授权码
my_user = s_mes["To"] # 接收人的邮箱
s_message = s_mes['message']
try:
# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
msg = MIMEText(str(s_message), 'plain', 'utf-8') # 发送的内容
msg['From'] = formataddr(['', my_sender]) # 好像没什么同
msg['To'] = formataddr(['', my_user]) #
msg['Subject'] = s_mes['Subject'] # 发送的主题
server = smtplib.SMTP_SSL("smtp.qq.com", 465) # 服务器的地址和端口其他邮箱端口百度
server.login(my_sender, my_pass) # 登录的账号密码
server.sendmail(my_sender, [my_user, ], msg.as_string()) #
server.quit() # 关闭连接
return True
except Exception as e:
print(e)
return False
需要注意下面几点:
我们仅仅需要查看未读的邮件,需要获取发件人的信息和邮件的内容。
没有信息返回None
在获取邮件内容的时候,注意会有编码问题,特别注意,把信息转字符串后会有:
网页的东西,需要进行数据清洗。def get_new_email(): # 用来查看信息
# 应该返回的也是一个列表,所有的信息在列表里面,方便查看
# 自动标记为已读,
all_message = {}
e_user = "你的邮箱" # 你的邮箱号
e_password = '****' # 你的授权码
host = "imap.qq.com"
port = 993 # 端口号
try:
server = imaplib.IMAP4_SSL(host=host, port=port)
print("已经连接")
server.login(e_user, e_password)
print("登录成功")
except:
print('连接出现问题!')
return None
num = str(server.select()[1]).replace('[b\'', '').replace(']', '').replace('\'', '')
count = int(num) - 1 # 获得最新的一封信的信息
# print(count)
# print("邮箱数量:"+num)
all_message['all_count'] = count
# 整体信息获取
typ, data = server.search(None, "Unseen") # 获取所有未读的信息
newlist = data[0].split() # 找最新的一封邮件
count = len(newlist)
print("未读邮件数量"+str(count))
all_message['Unseen_count'] = len(newlist)
# print(newlist[0])
# 标记最新的一封邮件为已读
if count == 0:
return None
server.store((newlist[0]), '+FLAGS', '(\\Seen)')
# print('标记最新邮件为已读')
typ, data = server.fetch(newlist[count-1], '(RFC822)') # 获得最新信封的数据数据 count表示第几封信
msg = email.message_from_string(data[0][1].decode('utf-8')) #
# 对主题进行获取 主题可能为空
try:
sub = msg.get('subject') # 获取主题
subdecode = email.header.decode_header(sub)[0][0] # 需要进行转码
# print("邮箱标题:", end='')
if subdecode:
all_message['Subject'] = subdecode.decode('UTF-8')
# print(subdecode.decode('UTF-8'))
else:
all_message['Subject'] = ''
# print('空')
except Exception as e:
all_message['Subject'] = str(e)
# print(e)
# 获取发件人的信息
name = msg.get('from')
name = str(email.header.decode_header(name))
name = str(re.findall(r'\D?\d*@qq\.com', name)).replace('[', '').replace(']', '').replace('\'', '').replace('<', '')
name = name.replace('\"', '')
all_message["name"] = str(name)
print("发件人:"+name)
message = ''
who = {}
# 获取邮件所有内容
try:
for part in msg.walk():
# 如果ture的话内容是没用的
if not part.is_multipart():
message = message + str(part.get_payload(decode=True).decode('utf-8'))
# 解码出文本内容,直接输出来就可以了
print(message) # 查看内容
server.close()
who[name] = message
all_message['message'] = message
return all_message
except Exception as e:
# # 无伤大雅,,,
# print("错误:"+e)
# print("HTML格式测试:")
try:
content = msg.get_payload()
content_charset = 'UTF-8'
content_charset = content[1].get_content_charset()
text = content[1].as_string().split('base64')[-1]
html_content = base64.b64decode(text).decode(content_charset)
message = str(html_content)
all_message['message'] = message
return all_message
except Exception as e:
print('错误'+e)
server.close()
all_message['message'] = ''
return None
下面的代码是通过读取文本来修改程序的一些参数
def is_admin(qq): # 判断是否是管理员发送的邮件
try:
with open("admin.txt", "r") as f:
admin = f.readlines()
for i in admin:
i = str(i).replace("\n", '')
if str(qq) == str(i):
# print("true")
return True
return False
except:
with open("admin.txt", "w+") as f:
f.write("***@qq.com\n") # 写你的邮箱
f.write("****@qq.com")
f.close()
return is_admin(qq)
def send_admin(): # 用来读取登录邮箱的账号,可以不用
name = {}
try:
with open("qq.txt", "r+") as f:
a = f.readline()
a = str(a).replace("\n", "")
b = a.split("#")
name["From"] = b
a = f.readline()
a = str(a).replace("\n", "")
b = a.split("#")
name["password"] = b
return name
except:
with open("qq.txt", "w+") as f:
f.write("From #***@qq.com\n") # 账号
f.write("password #****\n") # 授权码
f.close()
return send_admin()
主函数:
# -*- coding: UTF-8 -*-
import email
import base64 # 解码
import imaplib
import os
import re
import smtplib
import time
from email.mime.text import MIMEText
from email.utils import formataddr
import json
from email.header import decode_header # 解码邮件主题
# 将发送封装成一个类,然后把功能分成各个函数,方便以后修改
# 可以用邮箱远程控制后,就剩下cookie 的动态获取了
def get_new_email(): # 用来查看信息
# 应该返回的也是一个列表,所有的信息在列表里面,方便查看
# 自动标记为已读,
all_message = {}
e_user = "****@qq.com"
e_password = '****' # 授权码
host = "imap.qq.com"
port = 993 # 995 ?
try:
server = imaplib.IMAP4_SSL(host=host, port=port)
print("已经连接")
server.login(e_user, e_password)
print("登录成功")
except:
print('连接出现问题!')
return None
# [b'8'] 获得邮箱的数量,老办法,字符串!
num = str(server.select()[1]).replace('[b\'', '').replace(']', '').replace('\'', '')
count = int(num) - 1 # 获得最新的一封信的信息
# print(count)
# print("邮箱数量:"+num)
all_message['all_count'] = count
# 整体信息获取
typ, data = server.search(None, "Unseen") # 获取所有未读的信息
newlist = data[0].split() # 找最新的一封邮件
count = len(newlist)
print("未读邮件数量"+str(count))
all_message['Unseen_count'] = len(newlist)
# print(newlist[0])
# 标记最新的一封邮件为已读
if count == 0:
return None
server.store((newlist[0]), '+FLAGS', '(\\Seen)')
# print('标记最新邮件为已读')
typ, data = server.fetch(newlist[count-1], '(RFC822)') # 获得最新信封的数据数据 count表示第几封信
msg = email.message_from_string(data[0][1].decode('utf-8')) #
# 对主题进行获取 主题可能为空
try:
sub = msg.get('subject') # 获取主题
subdecode = email.header.decode_header(sub)[0][0] # 需要进行转码
# print("邮箱标题:", end='')
if subdecode:
all_message['Subject'] = subdecode.decode('UTF-8')
# print(subdecode.decode('UTF-8'))
else:
all_message['Subject'] = ''
# print('空')
except Exception as e:
all_message['Subject'] = str(e)
# print(e)
# 获取发件人的信息
name = msg.get('from')
name = str(email.header.decode_header(name))
name = str(re.findall(r'\D?\d*@qq\.com', name)).replace('[', '').replace(']', '').replace('\'', '').replace('<', '')
name = name.replace('\"', '')
all_message["name"] = str(name)
print("发件人:"+name)
message = ''
who = {}
# 获取邮件所有内容
try:
for part in msg.walk():
# 如果ture的话内容是没用的
if not part.is_multipart():
message = message + str(part.get_payload(decode=True).decode('utf-8'))
# 解码出文本内容,直接输出来就可以了
print(message) # 查看内容
server.close()
who[name] = message
all_message['message'] = message
return all_message
except Exception as e:
# # 无伤大雅,,,
# print("错误:"+e)
# print("HTML格式测试:")
try:
content = msg.get_payload()
content_charset = 'UTF-8'
content_charset = content[1].get_content_charset()
text = content[1].as_string().split('base64')[-1]
html_content = base64.b64decode(text).decode(content_charset)
message = str(html_content)
all_message['message'] = message
return all_message
except Exception as e:
print('错误'+e)
server.close()
all_message['message'] = ''
return None
def send_email(s_mes):
my_sender = s_mes["From"] # 发送人的账号
my_pass = s_mes["password"] # 授权码
my_user = s_mes["To"] # 接收人的邮箱
s_message = s_mes['message']
try:
# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
msg = MIMEText(str(s_message), 'plain', 'utf-8') # 发送的内容
msg['From'] = formataddr(['', my_sender]) # 好像没什么同
msg['To'] = formataddr(['', my_user]) #
msg['Subject'] = s_mes['Subject'] # 发送的主题
server = smtplib.SMTP_SSL("smtp.qq.com", 465) # 服务器的地址和端口
server.login(my_sender, my_pass) # 登录的账号密码
server.sendmail(my_sender, [my_user, ], msg.as_string()) #
server.quit() # 关闭连接
return True
except Exception as e:
print(e)
return False
def is_admin(qq):
try:
with open("admin.txt", "r") as f:
admin = f.readlines()
for i in admin:
i = str(i).replace("\n", '')
if str(qq) == str(i):
# print("true")
return True
return False
except:
with open("admin.txt", "w+") as f:
f.write("***@qq.com\n")
f.write("***@qq.com")
f.close()
return is_admin(qq)
def send_admin():
name = {}
try:
with open("qq.txt", "r+") as f:
a = f.readline()
a = str(a).replace("\n", "")
b = a.split("#")
name["From"] = b
a = f.readline()
a = str(a).replace("\n", "")
b = a.split("#")
name["password"] = b
return name
except:
with open("qq.txt", "w+") as f:
f.write("From #****@qq.com\n")
f.write("password #**\n")
f.close()
return send_admin()
if __name__ == '__main__':
s_mes = {
'From': '****@qq.com',
'password': '***',
'To': '***@qq.com',
'Subject': '这是主题',
'message': "关机 3600",
}
test = send_admin()
s_mes["From"] = str(test["From"]).replace("['From ', '", '').replace("']", '')
s_mes["password"] = str(test["password"]).replace("['password ', '", '').replace("']", '')
# print(s_mes)
# print(test)
# time.sleep(1.5) # 设置延时,不然可能不会标记为已读
while True:
message = get_new_email()
if message == None: # None
print("没有人,休息30s")
time.sleep(30)
continue
if is_admin(message['name']):
content = message['message'].replace("\n", '').split(" ")
minling1 = str(content[0]).replace("", '').replace("", '')
minling2 = str(content[1]).replace("
测试成功后,用pyinstaller 打包成exe文件,同时将黑框框隐去,咋有点像后台,哈哈。
需要安装pyinstaller包,已经上面的库要在python环境里面,出现库错误,请看这里:传送门
cmd输入:pyinstaller -F py文件的路径 -w
-w 是隐去黑框框
再来点刺激的,打包后的exe文件,直接放到C盘自启文件夹里面
我的是:C:\Users\你的登录名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
在这个文件夹里面的程序开机会自启。
啧啧啧