🌱EUserv_tsf
This commit is contained in:
parent
b4050d036d
commit
c7b02e1a65
BIN
Scripts/py/BeautifulSoup .zip
Normal file
BIN
Scripts/py/BeautifulSoup .zip
Normal file
Binary file not shown.
252
Scripts/py/EUserv_tsf.py
Normal file
252
Scripts/py/EUserv_tsf.py
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
# -*- coding: utf8 -*-
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import requests
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
# 强烈建议部署在非大陆区域,例如HK、SG等
|
||||||
|
# 常量命名使用全部大写的方式,可以使用下划线。
|
||||||
|
USERNAME = os.environ.get('USERNAME') # 用户名,邮箱也可
|
||||||
|
PASSWORD = os.environ.get('PASSWORD') # 密码
|
||||||
|
|
||||||
|
# Server酱 http://sc.ftqq.com/?c=code
|
||||||
|
SCKEY = os.environ.get('SCKEY') # Server酱的key,无需推送可不填 示例: SCU646xxxxxxxxdacd6a5dc3f6
|
||||||
|
|
||||||
|
# 酷推 https://cp.xuthus.cc
|
||||||
|
COOL_PUSH_SKEY = os.environ.get('COOL_PUSH_SKEY')
|
||||||
|
# 通知类型 CoolPush_MODE的可选项有(默认send):send[QQ私聊]、group[QQ群聊]、wx[个微]、ww[企微]
|
||||||
|
COOL_PUSH_MODE = os.environ.get('COOL_PUSH_MODE')
|
||||||
|
|
||||||
|
# PushPlus https://pushplus.hxtrip.com/message
|
||||||
|
PUSH_PLUS_TOKEN = os.environ.get('PUSH_PLUS_TOKEN')
|
||||||
|
|
||||||
|
# Telegram Bot Push https://core.telegram.org/bots/api#authorizing-your-bot
|
||||||
|
TG_BOT_TOKEN = os.environ.get('TG_BOT_TOKEN') # 通过 @BotFather 申请获得,示例:1077xxx4424:AAFjv0FcqxxxxxxgEMGfi22B4yh15R5uw
|
||||||
|
TG_USER_ID = os.environ.get('TG_USER_ID') # 用户、群组或频道 ID,示例:129xxx206
|
||||||
|
TG_API_HOST = 'api.telegram.org' # 自建 API 反代地址,供网络环境无法访问时使用,网络正常则保持默认
|
||||||
|
|
||||||
|
# wecomchan https://github.com/easychen/wecomchan
|
||||||
|
WECOMCHAN_DOMAIN = os.environ.get('WECOMCHAN_DOMAIN') # http(s)://example.com/
|
||||||
|
WECOMCHAN_SEND_KEY = os.environ.get('WECOMCHAN_SEND_KEY')
|
||||||
|
WECOMCHAN_TO_USER = '@all' # 默认全部推送, 对个别人推送可用 User1|User2
|
||||||
|
# 变量命名使用全部小写的方式,可以使用下划线。
|
||||||
|
desp = '' # 不用动
|
||||||
|
|
||||||
|
|
||||||
|
# 函数命名使用全部小写的方式,可以使用下划线。
|
||||||
|
def print_(info):
|
||||||
|
print(info)
|
||||||
|
global desp
|
||||||
|
desp = desp + info + '\n\n'
|
||||||
|
|
||||||
|
|
||||||
|
def login(username, password) -> (str, requests.session):
|
||||||
|
headers = {
|
||||||
|
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||||
|
"Chrome/83.0.4103.116 Safari/537.36",
|
||||||
|
"origin": "https://www.euserv.com",
|
||||||
|
}
|
||||||
|
url = "https://support.euserv.com/index.iphp"
|
||||||
|
session = requests.Session()
|
||||||
|
|
||||||
|
sess = session.get(url, headers=headers)
|
||||||
|
sess_id = re.findall("PHPSESSID=(\\w{10,100});", str(sess.headers))[0]
|
||||||
|
# 访问png
|
||||||
|
png_url = "https://support.euserv.com/pic/logo_small.png"
|
||||||
|
session.get(png_url, headers=headers)
|
||||||
|
|
||||||
|
login_data = {
|
||||||
|
"email": username,
|
||||||
|
"password": password,
|
||||||
|
"form_selected_language": "en",
|
||||||
|
"Submit": "Login",
|
||||||
|
"subaction": "login",
|
||||||
|
"sess_id": sess_id
|
||||||
|
}
|
||||||
|
f = session.post(url, headers=headers, data=login_data)
|
||||||
|
f.raise_for_status()
|
||||||
|
|
||||||
|
if f.text.find('Hello') == -1:
|
||||||
|
return '-1', session
|
||||||
|
return sess_id, session
|
||||||
|
|
||||||
|
|
||||||
|
def get_servers(sess_id: str, session: requests.session) -> {}:
|
||||||
|
d = {}
|
||||||
|
url = "https://support.euserv.com/index.iphp?sess_id=" + sess_id
|
||||||
|
headers = {
|
||||||
|
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||||
|
"Chrome/83.0.4103.116 Safari/537.36",
|
||||||
|
"origin": "https://www.euserv.com"
|
||||||
|
}
|
||||||
|
f = session.get(url=url, headers=headers)
|
||||||
|
f.raise_for_status()
|
||||||
|
soup = BeautifulSoup(f.text, 'html.parser')
|
||||||
|
for tr in soup.select('#kc2_order_customer_orders_tab_content_1 .kc2_order_table.kc2_content_table tr'):
|
||||||
|
server_id = tr.select('.td-z1-sp1-kc')
|
||||||
|
if not len(server_id) == 1:
|
||||||
|
continue
|
||||||
|
flag = True if tr.select('.td-z1-sp2-kc .kc2_order_action_container')[
|
||||||
|
0].get_text().find('Contract extension possible from') == -1 else False
|
||||||
|
d[server_id[0].get_text()] = flag
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
def renew(sess_id: str, session: requests.session, password: str, order_id: str) -> bool:
|
||||||
|
url = "https://support.euserv.com/index.iphp"
|
||||||
|
headers = {
|
||||||
|
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||||
|
"Chrome/83.0.4103.116 Safari/537.36",
|
||||||
|
"Host": "support.euserv.com",
|
||||||
|
"origin": "https://support.euserv.com",
|
||||||
|
"Referer": "https://support.euserv.com/index.iphp"
|
||||||
|
}
|
||||||
|
data = {
|
||||||
|
"Submit": "Extend contract",
|
||||||
|
"sess_id": sess_id,
|
||||||
|
"ord_no": order_id,
|
||||||
|
"subaction": "choose_order",
|
||||||
|
"choose_order_subaction": "show_contract_details"
|
||||||
|
}
|
||||||
|
session.post(url, headers=headers, data=data)
|
||||||
|
data = {
|
||||||
|
"sess_id": sess_id,
|
||||||
|
"subaction": "kc2_security_password_get_token",
|
||||||
|
"prefix": "kc2_customer_contract_details_extend_contract_",
|
||||||
|
"password": password
|
||||||
|
}
|
||||||
|
f = session.post(url, headers=headers, data=data)
|
||||||
|
f.raise_for_status()
|
||||||
|
if not json.loads(f.text)["rs"] == "success":
|
||||||
|
return False
|
||||||
|
token = json.loads(f.text)["token"]["value"]
|
||||||
|
data = {
|
||||||
|
"sess_id": sess_id,
|
||||||
|
"ord_id": order_id,
|
||||||
|
"subaction": "kc2_customer_contract_details_extend_contract_term",
|
||||||
|
"token": token
|
||||||
|
}
|
||||||
|
session.post(url, headers=headers, data=data)
|
||||||
|
time.sleep(5)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check(sess_id: str, session: requests.session):
|
||||||
|
print("Checking.......")
|
||||||
|
d = get_servers(sess_id, session)
|
||||||
|
flag = True
|
||||||
|
for key, val in d.items():
|
||||||
|
if val:
|
||||||
|
flag = False
|
||||||
|
print_("ServerID: %s Renew Failed!" % key)
|
||||||
|
if flag:
|
||||||
|
print_("ALL Work Done! Enjoy")
|
||||||
|
|
||||||
|
|
||||||
|
# Server酱 http://sc.ftqq.com/?c=code
|
||||||
|
def server_chan():
|
||||||
|
data = (
|
||||||
|
('text', 'EUserv续费日志'),
|
||||||
|
('desp', desp)
|
||||||
|
)
|
||||||
|
response = requests.post('https://sc.ftqq.com/' + SCKEY + '.send', data=data)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print('Server酱 推送失败')
|
||||||
|
else:
|
||||||
|
print('Server酱 推送成功')
|
||||||
|
|
||||||
|
|
||||||
|
# 酷推 https://cp.xuthus.cc/
|
||||||
|
def coolpush():
|
||||||
|
c = 'EUserv续费日志\n\n' + desp
|
||||||
|
data = json.dumps({'c': c})
|
||||||
|
url = 'https://push.xuthus.cc/' + COOL_PUSH_MODE + '/' + COOL_PUSH_SKEY
|
||||||
|
response = requests.post(url, data=data)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print('酷推 推送失败')
|
||||||
|
else:
|
||||||
|
print('酷推 推送成功')
|
||||||
|
|
||||||
|
|
||||||
|
# PushPlus https://pushplus.hxtrip.com/message
|
||||||
|
def push_plus():
|
||||||
|
data = (
|
||||||
|
('token', PUSH_PLUS_TOKEN),
|
||||||
|
('title', 'EUserv续费日志'),
|
||||||
|
('content', desp)
|
||||||
|
)
|
||||||
|
url = 'https://pushplus.hxtrip.com/send'
|
||||||
|
response = requests.post(url, data=data)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print('PushPlus 推送失败')
|
||||||
|
else:
|
||||||
|
print('PushPlus 推送成功')
|
||||||
|
|
||||||
|
|
||||||
|
# Telegram Bot Push https://core.telegram.org/bots/api#authorizing-your-bot
|
||||||
|
def telegram():
|
||||||
|
data = (
|
||||||
|
('chat_id', TG_USER_ID),
|
||||||
|
('text', 'EUserv续费日志\n\n' + desp)
|
||||||
|
)
|
||||||
|
response = requests.post('https://' + TG_API_HOST + '/bot' + TG_BOT_TOKEN + '/sendMessage', data=data)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print('Telegram Bot 推送失败')
|
||||||
|
else:
|
||||||
|
print('Telegram Bot 推送成功')
|
||||||
|
|
||||||
|
|
||||||
|
# wecomchan https://github.com/easychen/wecomchan
|
||||||
|
def wecomchan():
|
||||||
|
response = requests.get(WECOMCHAN_DOMAIN + 'wecomchan?sendkey=' + WECOMCHAN_SEND_KEY + '&msg_type=text' + '&to_user=' +
|
||||||
|
WECOMCHAN_TO_USER + '&msg=' + 'EUserv续费日志\n\n' + desp)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print('wecomchan 推送失败')
|
||||||
|
else:
|
||||||
|
print('wecomchan 推送成功')
|
||||||
|
|
||||||
|
|
||||||
|
def main_handler(event, context):
|
||||||
|
if not USERNAME or not PASSWORD:
|
||||||
|
print_("你没有添加任何账户")
|
||||||
|
exit(1)
|
||||||
|
user_list = USERNAME.strip().split()
|
||||||
|
passwd_list = PASSWORD.strip().split()
|
||||||
|
if len(user_list) != len(passwd_list):
|
||||||
|
print_("The number of usernames and passwords do not match!")
|
||||||
|
exit(1)
|
||||||
|
for i in range(len(user_list)):
|
||||||
|
print('*' * 30)
|
||||||
|
print_("正在续费第 %d 个账号" % (i + 1))
|
||||||
|
sessid, s = login(user_list[i], passwd_list[i])
|
||||||
|
if sessid == '-1':
|
||||||
|
print_("第 %d 个账号登陆失败,请检查登录信息" % (i + 1))
|
||||||
|
continue
|
||||||
|
servers = get_servers(sessid, s)
|
||||||
|
print_("检测到第 {} 个账号有 {} 台VPS,正在尝试续期".format(i + 1, len(servers)))
|
||||||
|
for k, v in servers.items():
|
||||||
|
if v:
|
||||||
|
if not renew(sessid, s, passwd_list[i], k):
|
||||||
|
print_("ServerID: %s Renew Error!" % k)
|
||||||
|
else:
|
||||||
|
print_("ServerID: %s has been successfully renewed!" % k)
|
||||||
|
else:
|
||||||
|
print_("ServerID: %s does not need to be renewed" % k)
|
||||||
|
time.sleep(15)
|
||||||
|
check(sessid, s)
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
# 五个通知渠道至少选取一个
|
||||||
|
SCKEY and server_chan()
|
||||||
|
COOL_PUSH_MODE and COOL_PUSH_SKEY and coolpush()
|
||||||
|
PUSH_PLUS_TOKEN and push_plus()
|
||||||
|
TG_BOT_TOKEN and TG_USER_ID and TG_API_HOST and telegram()
|
||||||
|
WECOMCHAN_DOMAIN and WECOMCHAN_SEND_KEY and WECOMCHAN_TO_USER and wecomchan()
|
||||||
|
|
||||||
|
print('*' * 30)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__': # 方便我本地调试
|
||||||
|
main_handler(None, None)
|
||||||
Loading…
Reference in New Issue
Block a user