本文目录导读:

- 核心逻辑
- 方案一:使用 WHOIS 查询(最通用,推荐)
- 方案二:使用 DNS 查询 (更简单,但不够精确)
- 方案三:使用第三方 API (最稳定,推荐)
- 方案四:使用云平台 SDK (如果域名在特定平台)
- 定时执行设置(最关键的一步)
- 推荐的最佳实践
- 如果需要完整可运行的代码模板
要设置域名过期预警,通常有几种主流方法,因为脚本需要定时执行(比如每天检查一次),所以最可靠的方式是结合 服务器定时任务(Cron) 或 云函数 来实现。
以下是几种常见的脚本实现方案,你可以根据自己熟悉的技术栈选择:
核心逻辑
脚本的核心是:查询域名的 Expiration Date(到期日期) -> 计算当前时间与到期日期的差值(剩余天数) -> 如果小于阈值(如30天、7天),则触发预警(发送邮件、短信、企业微信/钉钉通知等)。
使用 WHOIS 查询(最通用,推荐)
这是最直接的方式,通过 whois 命令或 Python 库查询。
Python 脚本 (使用 whois 库)
步骤:
- 安装库:
pip install python-whois - 编写脚本:
import whois
import datetime
import smtplib
from email.mime.text import MIMEText
import sys
# 需要监控的域名列表
DOMAINS = ["example.com", "google.com"]
# 预警阈值(天)
WARN_DAYS = 30
CRITICAL_DAYS = 7
# 邮件配置(示例,实际请使用环境变量)
SMTP_SERVER = "smtp.qq.com"
SMTP_PORT = 587
SENDER = "your_email@qq.com"
PASSWORD = "your_password" # 建议使用授权码
RECEIVER = "alert@yourcompany.com"
def check_domain(domain):
try:
w = whois.whois(domain)
# 部分域名的到期时间可能有多个值,取第一个
if isinstance(w.expiration_date, list):
expire_date = w.expiration_date[0]
else:
expire_date = w.expiration_date
if expire_date is None:
return f"[跳过] {domain}: 无法获取到期时间"
# 确保是datetime对象
if isinstance(expire_date, datetime.datetime):
days_left = (expire_date - datetime.datetime.now()).days
elif isinstance(expire_date, datetime.date):
days_left = (expire_date - datetime.date.today()).days
else:
return f"[错误] {domain}: 未知日期格式"
if days_left < 0:
return f"[已过期] {domain}: 已过期 {-days_left} 天!"
elif days_left <= CRITICAL_DAYS:
return f"[严重] {domain}: 仅剩 {days_left} 天过期!"
elif days_left <= WARN_DAYS:
return f"[预警] {domain}: 还剩 {days_left} 天过期。"
else:
return f"[正常] {domain}: 还剩 {days_left} 天过期。"
except Exception as e:
return f"[错误] {domain}: 查询失败 - {str(e)}"
def send_alert(message):
# 这里以邮件为例,也可以改为钉钉/企业微信webhook
msg = MIMEText(message, 'plain', 'utf-8')
msg['Subject'] = '域名过期预警通知'
msg['From'] = SENDER
msg['To'] = RECEIVER
try:
server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
server.starttls()
server.login(SENDER, PASSWORD)
server.sendmail(SENDER, RECEIVER, msg.as_string())
server.quit()
print("预警邮件发送成功")
except Exception as e:
print(f"邮件发送失败: {e}")
if __name__ == "__main__":
alerts = []
for domain in DOMAINS:
result = check_domain(domain)
print(result)
# 如果包含预警/严重/过期,记录到警报列表
if "预警" in result or "严重" in result or "过期" in result:
alerts.append(result)
# 如果有警报,发送通知
if alerts:
message = "\n".join(alerts)
send_alert(message)
Shell 脚本 (依赖系统 whois 命令)
#!/bin/bash
# 域名列表
DOMAINS=("example.com" "google.com")
WARN_DAYS=30
CRITICAL_DAYS=7
# 发送通知的函数(示例curl发送到企业微信)
send_notification() {
local msg="$1"
# 企业微信机器人示例
# curl -s -X POST "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY" \
# -H "Content-Type: application/json" \
# -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$msg\"}}"
echo "预警: $msg"
}
for domain in "${DOMAINS[@]}"; do
# 使用whois命令提取到期日期(格式因注册局而异,可能需要调整)
expire_date=$(whois "$domain" | grep -i "Expiration Date" | head -1 | awk '{print $NF}')
if [ -z "$expire_date" ]; then
echo "[跳过] $domain: 无法获取到期日期"
continue
fi
# 转换为时间戳(需根据日期格式调整)
expire_ts=$(date -d "$expire_date" +%s 2>/dev/null)
if [ $? -ne 0 ]; then
echo "[错误] $domain: 日期解析失败"
continue
fi
now_ts=$(date +%s)
days_left=$(( (expire_ts - now_ts) / 86400 ))
if [ "$days_left" -le 0 ]; then
echo "[已过期] $domain: 已过期$(( -days_left ))天"
send_notification "[已过期] $domain"
elif [ "$days_left" -le "$CRITICAL_DAYS" ]; then
echo "[严重] $domain: 仅剩${days_left}天"
send_notification "[严重] $domain"
elif [ "$days_left" -le "$WARN_DAYS" ]; then
echo "[预警] $domain: 还剩${days_left}天"
fi
done
使用 DNS 查询 (更简单,但不够精确)
某些域名有 SOA 记录的 expire 字段,但这通常是域名服务器层面的,不太推荐用来判断域名注册到期,因为 DNS 的过期时间与注册过期时间可能不同步,但可以作为备选。
使用第三方 API (最稳定,推荐)
WHOIS 查询在某些服务器上会被限制(频率过高会封IP),或者某些域名(如 .cn)查询速度很慢,使用 WHOIS API 可以避免这些问题。
- WhoisXML API / WhoisFreaks:提供免费额度,返回 JSON 数据。
- 阿里云/腾讯云 API:如果你域名在这些平台,可以使用官方 SDK。
# 以 WhoisXML API 为例
import requests
API_KEY = "your_api_key"
DOMAIN = "example.com"
url = f"https://www.whoisxmlapi.com/whoisserver/WhoisService?apiKey={API_KEY}&domainName={DOMAIN}&outputFormat=JSON"
response = requests.get(url)
data = response.json()
# 提取到期日期
expire_date = data['WhoisRecord']['registryData']['expiresDate']
# 后续逻辑同上...
使用云平台 SDK (如果域名在特定平台)
如果你使用的注册商是阿里云、腾讯云、AWS Route53、Namecheap等,使用它们的 SDK 是最精确的(可以访问你的账户信息)。
# 以阿里云为例(需要配合阿里云RAM子账户的AccessKey)
from aliyunsdkcore.client import AcsClient
from aliyunsdkdomain.request.v20180129.QueryDomainListRequest import QueryDomainListRequest
client = AcsClient('access_key_id', 'access_secret', 'cn-hangzhou')
request = QueryDomainListRequest()
request.set_page_size(100)
response = client.do_action_with_exception(request)
# 解析 response,获取每个域名的 expirationDate
定时执行设置(最关键的一步)
脚本写好后,需要让它每天自动运行一次。
Linux / macOS 使用 Crontab:
# 编辑定时任务 crontab -e # 每天早上9点执行python脚本,日志输出到文件 0 9 * * * /usr/bin/python3 /path/to/domain_check.py >> /var/log/domain_alert.log 2>&1
Windows 使用任务计划程序:
- 打开“任务计划程序”。
- 创建基本任务 -> 触发器设为每天 -> 操作选择启动 Python 脚本。
推荐的最佳实践
- 不要单点依赖: 结合一个简单的 WHOIS API(类似 whoisjson.com)作为主要来源,再用一个本地 whois 作为备用。
- 通知方式:
- 免费/便捷: 企业微信/钉钉机器人(Webhook)、Telegram Bot、Pushover。
- 稳定: 邮件(SMTP)。
- 可靠: 短信(需付费,如 Twilio、阿里云短信)。
- 安全: 不要将 API 密钥、邮箱密码硬编码在脚本中,使用环境变量(
os.getenv('API_KEY'))或单独的配置文件。 - 多域名管理: 使用 YAML 或 JSON 配置文件维护域名列表,而不是写在脚本里。
如果需要完整可运行的代码模板
这里有一个可以直接用的 Python 脚本(集成企业微信通知、环境变量配置)——如果你需要,告诉我,我可以写一个更完善的版本给你。