黑五促销季:用一个 Python 脚本盯住 VPS 价格变动

黑五促销季:用一个 Python 脚本盯住 VPS 价格变动

为什么写这个脚本

每年 10 月底到 12 月是 VPS 促销最密集的两个月:双十一、黑五、网一轮番上阵。今年 10.10 已经有商家开跑,比如 OrangeVPS 的年付 5 折促销,用优惠码后美国机房 $19.2/年起。

但促销价不是钉死的:限量套餐卖完就下架、优惠码可能提前失效、有些"折扣"第二年就恢复原价。人工每天刷几个促销页又累又容易错过。干脆写个 60 行的 Python 小脚本,让它每天自动抓一次价格快照,价格一变就告诉你。

这篇文章的目标读者:会装 Python、能看懂简单脚本的 VPS 玩家。写完之后你手里就有了一个可用的价格哨兵,黑五期间盯促销、平时盯续费价都用得上。

先想清楚:促销价要盯什么

下手之前,先搞懂促销价的三种套路(参考自 2026 双十一/黑五 VPS 购买攻略 的总结):

  • 循环折扣:续费一直按折扣价,比如搬瓦工的循环优惠码;
  • 续费同价:特价套餐,续费还是这个价,比如 RackNerd 的经典特价机;
  • 仅首年:第二年恢复原价,大部分"新用户价"都是这种。

我们的脚本只解决一件事:盯住页面上的标价,变了就报警。至于它是循环折扣还是首年价,下单前还得人工去结算页确认——这也是本站 2026 年黑五 VPS 购买实战清单 里反复强调的:优惠码、续费价、退款政策,下单前逐项核对。

脚本:vps_promo_watch.py

设计刻意保持简单:只用 Python 标准库(urllib + re + json),零第三方依赖,丢到任何一台 VPS 上都能跑。

逻辑分三步:

  1. 按配置列表逐个抓取促销页,用正则提取价格;
  2. 和上次的 JSON 快照对比;
  3. 价格变了就打印提醒,更新快照。
#!/usr/bin/env python3
"""vps_promo_watch.py —— 抓取促销页价格快照,价格变动时提醒(仅用标准库)"""
import json, os, re, urllib.request
from datetime import datetime

SNAPSHOT = "price_snapshot.json"  # 上次价格存这里,和脚本放同一目录

# 想盯的页面:name 自己起名字,url 换成真实促销页,
# pattern 写能匹配页面价格的正则(先 view-source 看一眼页面源码)
TARGETS = [
    {
        "name": "示例商家-洛杉矶年付",
        "url": "https://example.com/promo-page",
        "pattern": r"\$\s?(\d+(?:\.\d+)?)\s?/年",
    },
    {
        "name": "示例商家-香港月付",
        "url": "https://example.com/hk-promo",
        "pattern": r"\$\s?(\d+(?:\.\d+)?)\s?/月",
    },
]

def fetch(url):
    req = urllib.request.Request(
        url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
    )
    with urllib.request.urlopen(req, timeout=30) as r:
        return r.read().decode("utf-8", "ignore")

def main():
    old = json.load(open(SNAPSHOT)) if os.path.exists(SNAPSHOT) else {}
    new = {}
    for t in TARGETS:
        try:
            html = fetch(t["url"])
        except Exception as e:
            print(f"[{t['name']}] 抓取失败:{e}")
            continue
        prices = [float(x) for x in re.findall(t["pattern"], html)]
        if not prices:
            print(f"[{t['name']}] 页面里没匹配到价格,检查 pattern")
            continue
        price = min(prices)  # 页面有多个价格时取最低的
        new[t["name"]] = price
        if t["name"] in old and old[t["name"]] != price:
            arrow = "📉 降价" if price < old[t["name"]] else "📈 涨价"
            print(f"{arrow} {t['name']}:${old[t['name']]} → ${price}({datetime.now():%m-%d %H:%M})")
        else:
            print(f"[OK] {t['name']} 当前 ${price}")
    json.dump(new, open(SNAPSHOT, "w"), indent=2, ensure_ascii=False)

if __name__ == "__main__":
    main()

跑起来 + 定时

# 先手动跑一次,生成初始快照
python3 vps_promo_watch.py

# 用 cron 每天早晚各跑一次(黑五期间可以改成每 6 小时)
crontab -e
# 加一行:
0 9,21 * * * cd /root/promo-watch && python3 vps_promo_watch.py >> watch.log 2>&1

建议单独建个目录(比如 /root/promo-watch)放脚本和快照,别和别的项目混在一起。

三个实战经验

1. 价格只是标价,结算页为准。 页面抓到的数字和最终付款金额可能不一样:优惠码要在结算时手动填、税费另算。上面提到的 OrangeVPS 促销,原文也注明"实际购买价格及优惠码适用情况以结算页面为准"。脚本负责发现变动,下单前的人工核对省不掉。

2. 顺手盯住"下架"。 连续两次抓不到价格(pattern 匹配为空),多半是促销页改版或套餐售罄。我的做法是把这种情况也写进日志——黑五期间限量机型经常"悄悄下架"。

3. 提醒通道按需升级。 打印到日志适合先跑一周观察误报率。稳定之后可以加一行推送:Bark(iOS)、Telegram Bot 或者发邮件。注意:推送内容里不要带任何账号、密码、token,纯价格信息就够了——密钥凭证只进配置文件,不进代码和日志。

还能怎么玩

  • 把快照换成 SQLite,攒一个月就是一条价格曲线,黑五结束还能复盘"到底便宜了多少"。
  • 和本站的 /promos/ 促销监控页 思路一样:定期抓取 + 人工整理,机器负责发现,人工负责核实。
  • 想盯的页面多了(比如同时看五六家),把 TARGETS 抽成单独的 targets.json,改配置不用动代码。

黑五还有一个多月,脚本先跑起来攒基线。等促销真正开跑,降价提醒会自己找上门。