检测公网 ip 变化后发送邮箱(二)- 检测公网 ip 是否改变

上次搞定发送邮箱的代码以后,接下来就是如果获取自己的公网 ip 了。通过对比 ip 地址,判断是否需要发送邮件。

获取 ip 地址的网站也有很多,如:https://myip4.ipip.net, https://ddns.oray.com/checkip, https://ip.3322.net 等等。

大家可以试试,返回的就是你所在网络的出口公网 ip 地址。

其实如果想要自己搭建一个这样的服务真的非常简单,只需要一个 nginx 。

其实只需要修改 nginx 的 default.conf 即可。

server {
  listen 80;
  server_name  localhost;

  location / {
    default_type text/plain;
    return 200 "$remote_addr";
  }
}

修改后,启动 nginx,然后访问就能得到自己的 ip 了,熟悉 nginx 的话应该不难看懂这个配置。

但是搭建好的服务需要放在公网,因为如果是局域网搭建的话,请求压根不会经过运营商,自然也就获取不到公网了,返回的是局域网地址。

我也是做了一个 docker 镜像上传到了仓库。运行 docker run -d -p 80:80 hausen1012/myip 即可,有兴趣的可以去试试。

下面分享下检测 ip 并发送邮件的完整代码。

import os
import requests
import re
import time
# smtplib 用于邮件的发信动作
import smtplib
# email 用于构建邮件内容
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 构建邮件头
from email.header import Header

def current_ip():
  headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"}
  html = requests.get('https://ddns.oray.com/checkip', headers=headers)

  currentIp = re.findall( r'[0-9]+(?:\.[0-9]+){3}',html.text)[0]
  return currentIp

def sendmail(oldIp, currentIp):
  # 发信方的信息:发信邮箱,QQ 邮箱授权码
  from_addr = 'xxx@qq.com'
  password = 'xxx'
  # 收信方邮箱
  to_addr = 'xxx@qq.com'
  # 发信服务器
  smtp_server = 'smtp.qq.com'

  template = """
  <p>主人,您的 ip 地址改变啦!</p>
  <p>原 ip 地址:{0}</p>
  <p>现 ip 地址:{1}</p>
  """
  html_msg = template.format(oldIp, currentIp)

  # 创建一个带附件的实例msg
  msg = MIMEMultipart()
  msg['From'] = Header('发送者')  # 发送者
  msg['To'] = Header('接收者')  # 接收者
  subject = 'IP 地址改变提醒'
  msg['Subject'] = Header(subject, 'utf-8')  # 邮件主题
  # 邮件正文内容
  msg.attach(MIMEText(html_msg, 'html', 'utf-8'))

  try:
    smtpobj = smtplib.SMTP_SSL(smtp_server)
    smtpobj.connect(smtp_server, 465)    # 建立连接--qq邮箱服务和端口号
    smtpobj.login(from_addr, password)   # 登录--发送者账号和口令
    smtpobj.sendmail(from_addr, to_addr, msg.as_string())
    print("邮件发送成功")
  except smtplib.SMTPException:
    print("无法发送邮件")
  finally:
    # 关闭服务器
    smtpobj.quit()

if __name__ == '__main__':

    # 随意设置原 ip
    oldIp = "127.0.0.1"
    while True:
      currentIp = current_ip()
      print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + "---oldIp:" + oldIp + ",currentIp:" + currentIp)
      if(oldIp != currentIp):
        print("Ip 地址发生改变")
        sendmail(oldIp, currentIp)
        oldIp = currentIp
      time.sleep(5) 

下面是测试结果,同样是完美运行。

代码日志:

post-572-632ee5dc4d713

邮件内容:

post-572-632ee5e28e1fb

使用脚本需要注意的是修改邮箱配置。

晚点做一个 docker 镜像,将邮箱配置、检测间隔作为参数,运行时传参即可。

阅读剩余
THE END