当前位置:论坛首页 > Linux面板 > 求助

python对接宝塔api,部署证书需要传哪些参数

发表在 Linux面板2025-8-4 16:00 [复制链接] 0 139

为了能快速了解并处理您的问题,请提供以下基础信息:
面板、插件版本:

9.6.0
系统版本:
Debian 12
问题描述:
我使用python对接宝塔api,获取网站列表找到没有安装证书的网站,并一一给他们安装证书,现在的问题是一直报指定参数无效

运行日志:
证书类型列表: {
  "status": false,
  "msg": "指定参数无效!"
}

筛选出 1 个需要申请证书的站点

申请证书: predico.top 域名: ['predico.top']
请求参数: {'request_time': '1754294275', 'request_token': 'dce115aa6426b95ce3c1d51b36136d05', 'data': '{"siteName": "predico.top", "domains": ["predico.top"], "email": "16639535636@163.com", "type": 1}'}
响应状态码: 200
响应内容: {"status": false, "msg": "\u6307\u5b9a\u53c2\u6570\u65e0\u6548!"}
❌ 证书申请失败: predico.top,原因: 指定参数无效!
相关截图(日志、错误):这是我的代码
import requests
import time
import hashlib
import json
import urllib3

# 关闭 HTTPS 警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

BT_PANEL = ""  # 替换为你的宝塔面板地址
API_KEY = ""  # 替换为你的API密钥

def get_token():
    request_time = str(int(time.time()))
    key_md5 = hashlib.md5(API_KEY.encode()).hexdigest()
    request_token = hashlib.md5((request_time + key_md5).encode()).hexdigest()
    return {"request_time": request_time, "request_token": request_token}

def get_sites():
    url = f"{BT_PANEL}/data?action=getData&table=sites"
    payload = get_token()
    payload.update({
        "p": 1,
        "limit": 1000,
    })

    print(f"请求站点列表接口: {url}")
    try:
        r = requests.post(url, data=payload, verify=False, timeout=15)
        r.raise_for_status()
        data = r.json()
        if data.get("status") is False:
            print("❌ 获取站点失败,原因:", data.get("msg"))
            return []
        sites = data.get("data", [])
        print(f"获取站点成功,共 {len(sites)} 个站点")
        return sites
    except Exception as e:
        print(f"获取站点异常: {e}")
        return []

def get_cert_types():
    url = f"{BT_PANEL}/ssl?action=GetCertType"
    payload = get_token()
    print(f"请求证书类型接口: {url}")
    try:
        r = requests.post(url, data=payload, verify=False, timeout=15)
        r.raise_for_status()
        res = r.json()
        print("证书类型列表:", json.dumps(res, indent=2, ensure_ascii=False))
        return res
    except Exception as e:
        print(f"获取证书类型异常: {e}")
        return None

def apply_ssl(site_name, email, domains):
    url = f"{BT_PANEL}/ssl?action=ApplyCert"
    payload = get_token()
    data = {
        "siteName": site_name,
        "domains": domains,
        "email": email,
        "type": 1  # 根据get_cert_types接口确认的值,这里先用1
        # "force_https": 1,  # 需要的话可以加上,先简化调试
        # "key_type": 1,
        # "key_length": 2048
    }
    payload["data"] = json.dumps(data)

    print(f"\n申请证书: {site_name} 域名: {domains}")
    print(f"请求参数: {payload}")
    try:
        r = requests.post(url, data=payload, verify=False, timeout=30)
        print(f"响应状态码: {r.status_code}")
        print(f"响应内容: {r.text}")
        r.raise_for_status()
        res = r.json()
        if res.get("status"):
            print(f"✅ 证书申请成功: {site_name}")
        else:
            print(f"❌ 证书申请失败: {site_name},原因: {res.get('msg', '未知错误')}")
    except Exception as e:
        print(f"申请证书异常: {site_name},异常: {e}")

def main():
    # 邮箱请替换成你的域名管理员邮箱
    email = ""
    sites = get_sites()
    if not sites:
        print("无站点数据,退出。")
        return

    # 先打印证书类型,确认type参数
    get_cert_types()

    # 筛选需要申请证书的站点,假设ssl字段 -1表示无证书
    to_apply = []
    for s in sites:
        ssl_info = s.get("ssl", -1)
        if ssl_info == -1 or ssl_info is None or ssl_info == {}:
            to_apply.append(s)

    print(f"\n筛选出 {len(to_apply)} 个需要申请证书的站点")

    for site in to_apply:
        site_name = site["name"]
        domains = [site_name, f"www.{site_name}"]
        apply_ssl(site_name, email, domains)

if __name__ == "__main__":
    main()




使用道具 举报 只看该作者 回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

普通问题处理

论坛响应时间:72小时

问题处理方式:排队(仅解答)

工作时间:白班:9:00 - 18:00

紧急运维服务

响应时间:3分钟

问题处理方式:宝塔专家1对1服务

工作时间:工作日:9:00 - 18:30

宝塔专业团队为您解决服务器疑难问题

点击联系技术免费分析

工作时间:09:00至18:30

快速回复 返回顶部 返回列表