【python】获取PC机公网IP并发送至邮箱

文章目录

  • 0.引言
  • 1.获取外网IP
  • 2.打开SMTP服务
  • 3.python发送邮件
  • 4.完整代码

0.引言

\qquad 之前一直使用Putty连接公司的PC机进行远程办公,苦于外网的IP地址不能固定下来,所以购买了内网穿透服务,免费版还会限速。后来转念一想,如果能定时获取PC机的外网IP并发送到自己的设备上,不就不需要内网穿透服务了吗,于是就有了本文。需要远程办公的朋友们建议收藏。

1.获取外网IP

\qquad 获取外网IP的方式有很多种,直接通过命令行或者登录网页即可:
Linux下获取外网IP
Windows下获取外网IP
\qquad 你可以利用shell命令定时获取IP并执行一个发送邮件的python文件,但是这样太过繁琐,于是我将获取IP的方式整合到了python中(其实是参考了别人的博客,但是回头找真的找不到是哪篇了,在此还是感谢这位博主,因为它的方法确实比其他人的简单)

from urllib.request import urlopen
my_ip = urlopen('http://ip.42.pl/raw').read()
my_ip = my_ip.decode(encoding='utf-8')  # ip str

这样就会返回string类型的IP地址了,需要注意的是获取频次不能太快(>10s),timeout也不宜太小(>3s),否则可能会报urlopen.error。

2.打开SMTP服务

\qquad python邮件发送属于第三方服务,需要邮箱开启SMTP服务,以QQ邮箱为例,网易的和学校公邮一般也有这个功能,代码也是通用的。
第一步:在设置中找到账户
【python】获取PC机公网IP并发送至邮箱_第1张图片
第二步:找到SMTP服务,点击开启(需要手机向一个号码发送短信,是要钱的,不过也就一条短信费用)。
【python】获取PC机公网IP并发送至邮箱_第2张图片
最好把授权码复制下来,不然还得再花一次冤枉钱再发一次。
授权码
授权码一定不能泄露!不放心的朋友最好设置自己不常用不绑定信息的邮箱作为测试邮箱。

3.python发送邮件

\qquad 打开SMTP服务之后的邮箱可以作为发送邮箱,而接收邮箱则不需要其打开SMTP服务,只需要知道邮箱号即可。以下是一个例子,其实发送者不是QQ邮箱也行,只要是打开过SMTP服务的就可以。

def send_email():  
    host_server = 'smtp.qq.com'  #qq邮箱smtp服务器
    sender_qq = '[email protected]' #发件人邮箱
    pwd = "xxxxxxxxxx"  # 授权码 str格式
    receiver = ['[email protected]','[email protected]']#收件人邮箱
    mail_title = 'Python自动发送的邮件' #邮件标题
    mail_content = "您好,这是python自动发送的邮件,请查收。"#邮件正文内容
    # 初始化一个邮件主体
    msg = MIMEMultipart()
    msg["Subject"] = Header(mail_title,'utf-8')
    msg["From"] = sender_qq
    # msg["To"] = Header("测试邮箱",'utf-8')
    msg['To'] = ";".join(receiver)
    # 邮件正文内容
    msg.attach(MIMEText(mail_content,'plain','utf-8'))
    smtp = SMTP_SSL(host_server) # ssl登录
    
    # login(user,password):
    # user:登录邮箱的用户名。
    # password:登录邮箱的密码,像笔者用的是网易邮箱,网易邮箱一般是网页版,需要用到客户端密码,需要在网页版的网易邮箱中设置授权码,该授权码即为客户端密码。
    smtp.login(sender_qq,pwd)
    
    # sendmail(from_addr,to_addrs,msg,...):
    # from_addr:邮件发送者地址
    # to_addrs:邮件接收者地址。字符串列表['接收地址1','接收地址2','接收地址3',...]或'接收地址'
    # msg:发送消息:邮件内容。一般是msg.as_string():as_string()是将msg(MIMEText对象或者MIMEMultipart对象)变为str。
    smtp.sendmail(sender_qq,receiver,msg.as_string())
    
    # quit():用于结束SMTP会话。
    smtp.quit()
    

4.完整代码

\qquad 以下例程,填好抬头的必要信息之后就可以直接运行了。注意文件名不要取email.py,会和email模块冲突!最后提醒大家方便自己远程办公的同时也要保护好自己的个人信息,尤其是授权码。
\qquad 获取IP的速度是10s一次,可以通过修改对应注释的Timer定时器的数值(单位:s)调整,默认模式是监测到PC机的外网IP变化时向指定邮箱发送。为防止出现urlopen.error终止程序,还得加上异常处理,如下图即是工作中可能出现的异常:
IP

# -*- coding: utf-8 -*-
from smtplib import SMTP_SSL
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header

from urllib.request import urlopen
import threading
import datetime
import sys
# smtplib模块主要负责发送邮件:是一个发送邮件的动作,连接邮箱服务器,登录邮箱,发送邮件(有发件人,收信人,邮件内容)。
# email模块主要负责构造邮件:指的是邮箱页面显示的一些构造,如发件人,收件人,主题,正文,附件等。
my_ip = urlopen('http://ip.42.pl/raw',timeout=5).read()
my_ip = my_ip.decode(encoding='utf-8')
sender_qq ='[email protected]'  # 发送邮箱
receiver = ['[email protected]','[email protected]']  # 接收邮箱
pwd = "xxxxx"   # 授权码
def send_email(my_ip,time=None):  
    host_server = 'smtp.qq.com'  #qq邮箱smtp服务器
    mail_title = 'Python自动发送的邮件' #邮件标题
    mail_content = "外网IP:{}\n发送时间:{}".format(my_ip,time) #邮件正文内容
    # 初始化一个邮件主体
    msg = MIMEMultipart()
    msg["Subject"] = Header(mail_title,'utf-8')
    msg["From"] = sender_qq
    # msg["To"] = Header("测试邮箱",'utf-8')
    msg['To'] = ";".join(receiver)
    # 邮件正文内容
    msg.attach(MIMEText(mail_content,'plain','utf-8'))
    smtp = SMTP_SSL(host_server) # ssl登录
    
    # login(user,password):
    # user:登录邮箱的用户名。
    # password:登录邮箱的密码,像笔者用的是网易邮箱,网易邮箱一般是网页版,需要用到客户端密码,需要在网页版的网易邮箱中设置授权码,该授权码即为客户端密码。
    smtp.login(sender_qq,pwd)
    
    # sendmail(from_addr,to_addrs,msg,...):
    # from_addr:邮件发送者地址
    # to_addrs:邮件接收者地址。字符串列表['接收地址1','接收地址2','接收地址3',...]或'接收地址'
    # msg:发送消息:邮件内容。一般是msg.as_string():as_string()是将msg(MIMEText对象或者MIMEMultipart对象)变为str。
    smtp.sendmail(sender_qq,receiver,msg.as_string())
    
    # quit():用于结束SMTP会话。
    smtp.quit()
    
def ip_render():
    global my_ip
    global timer
    try:
        date_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        new_ip = urlopen('http://ip.42.pl/raw').read()
        new_ip = new_ip.decode(encoding='utf-8')
        if new_ip != my_ip:
            my_ip = new_ip
            send_email(my_ip,time=date_time)
            print('IP changed:{} -time:{}'.format(my_ip,date_time))
        else:
            sys.stdout.write("\rIP doesn't change -time:{}".format(date_time))
            sys.stdout.flush()
    except Exception as e:
        print("Exception:{}".format(e))
    timer = threading.Timer(30, ip_render)  # 30s 获取IP一次
    timer.start()
if __name__ == "__main__":
    print('IP:{}'.format(my_ip))
    timer = threading.Timer(5, ip_render)  # 5s后开始循环线程
    timer.start()
    

希望本文对您有帮助,谢谢阅读!

你可能感兴趣的:(Python,Linux,python,IP,SMTP,邮件服务,远程办公)