为了能快速了解并处理您的问题,请提供以下基础信息:
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()
|
|