⏰ 第08章 · Python 脚本自动化
贴吧签到/监控报告实践
Python 脚本自动化¶
这一章讲这台服务器上真实在跑的两种 Python 自动化脚本:贴吧签到(tieba_sign.py)和监控报告(monitor_report.py)。它们展示了"无浏览器"调用 HTTP 接口、读配置、处理数据、推送通知、被 cron 调度的完整套路。学会这套,你就能写自己的自动化脚本。
脚本模式概览¶
| 模式 | 说明 | 本机例子 |
|---|---|---|
| 读配置 | 从配置文件/环境变量取凭证 | 读 /root/.tieba_bduss、/root/.feishu_monitor.conf |
| 无浏览器调接口 | 用标准库 urllib 发 HTTP |
调贴吧 / 飞书接口 |
| 数据处理 | 解析 JSON、计算、生成图表 | 监控脚本用 matplotlib 画图 |
| 推送通知 | HTTP 回调到聊天机器人 | 发飞书群消息 |
| 被调度 | cron 每日执行 | crontab -l 可见 |
为什么用标准库(urllib)而不是 requests¶
本机脚本特别强调"零依赖""无需浏览器",因为生产服务器尽量少装东西、少被网络限制绑架。Python 标准库 urllib.request/urllib.parse 足够发 GET/POST、带 header、处理 JSON。
import urllib.request, urllib.parse, json
# GET
with urllib.request.urlopen("https://example.com/api", timeout=10) as r:
data = json.loads(r.read())
# POST JSON(带 header)
req = urllib.request.Request(
"https://example.com/api",
data=json.dumps({"k": "v"}).encode(),
headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=15) as r:
resp = json.loads(r.read())
提示 | 有
requests库会更顺手,但它不是标准库,需要pip install。在"能少装就不装"的服务器/脚本里,urllib是安全底座。必要时可用venv隔离装依赖。
贴吧签到脚本的要点¶
它用"BDUSS/STOKEN"这个登录凭证调贴吧客户端接口:
# 凭证两种放法:环境变量 或 配置文件(建议 chmod 600)
export TIEBA_BDUSS="..."
export TIEBA_STOKEN="..."
# 或写入
echo "你的BDUSS值" > /root/.tieba_bduss && chmod 600 /root/.tieba_bduss
关键逻辑:
def load_bduss():
env = os.environ.get("TIEBA_BDUSS", "").strip()
if env: return env
# 从配置文件读
try:
with open("/root/.tieba_bduss") as f:
return f.read().strip()
except Exception:
return ""
def http_json(url, bduss, stoken="", data=None):
headers = {"User-Agent": "...", "Cookie": build_cookie(bduss, stoken)}
req = urllib.request.Request(url, data=urllib.parse.urlencode(data).encode() if data else None,
headers=headers)
with urllib.request.urlopen(req, timeout=15) as r:
return json.loads(r.read())
安全 | BDUSS/STOKEN 等同于账号钥匙。脚本用
chmod 600保护凭证文件;不要把它写进版本库、不要打印到日志。
监控报告脚本的要点(macplotlib 画图 + 飞书推送)¶
它从 Prometheus 取时序数据、生成多面板仪表盘图片、上传到飞书:
import matplotlib
matplotlib.use("Agg") # 无显示环境用 Agg 后端,必须放在 import pyplot 之前
import matplotlib.pyplot as plt
def query_range(server, query, start, end, step="60s"):
p = urllib.parse.urlencode({"query": query, "start": start, "end": end, "step": step})
with urllib.request.urlopen(f"{server}/api/v1/query_range?{p}", timeout=10) as r:
return json.loads(r.read())
- 注册中文字体:否则中文会变方块。代码里注册 Noto CJK / 文泉驿 / 微软雅黑等字体路径。
- 生成图片:
plt.savefig到内存io.BytesIO,再 base64 上传。 - 飞书机器人:拿
app_id/app_secret换tenant_access_token,再调上传图片/发送卡片接口。
def get_token(): # 从配置读 app_id/app_secret,POST 换取 access_token
data = json.dumps({"app_id": APP_ID, "app_secret": APP_SECRET}).encode()
req = urllib.request.Request(TOKEN_URL, data=data, headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=10) as r:
return json.loads(r.read())["tenant_access_token"]
def send_card(card): # 发富文本卡片到群
body = json.dumps({"msg_type": "interactive", "content": json.dumps(card)}).encode()
req = urllib.request.Request(WEBHOOK, data=body,
headers={"Content-Type": "application/json; charset=utf-8"})
with urllib.request.urlopen(req, timeout=15) as r:
return json.loads(r.read())
注意 | 飞书机器人有多种:自定义 Webhook 机器人 与 应用机器人。应用机器人需要
app_id/app_secret换 token;自定义机器人只需一个 webhook 地址。按你的机器人类型选用对应的鉴权方式。
让脚本健壮的通用手法¶
| 手法 | 作用 |
|---|---|
timeout=15 |
调外部接口设超时,避免长时间挂住 |
用 try/except 捕获网络异常 |
失败时打日志,而不是让整个脚本崩掉 |
import logging 或 print 到日志 |
便于 cron 排查(重定向到日志文件) |
| 配置集中放一个文件 | 本机读 /root/.feishu_monitor.conf,改配置不用改代码 |
凭证 chmod 600 |
安全 |
用 flock 防并发 |
避免两个实例互相干扰 |
相关命令¶
- 手动调试:
/usr/bin/python3 /root/scripts/tieba_sign.py - 加可执行权限:
chmod +x - 看日志:
tail -n 50 /var/log/tieba_sign.log - 定时执行:参考《定时任务实战》里的 crontab 写法。