#!/usr/bin/env python3 # _*_ coding:utf-8 _*_ # 觉得好用请点 *star*,作者仓库:https://github.com/rpgrpg/freenom-qinglong.git ''' cron: 33 7 * * 2,5 new Env:('freenom多帐户续期'); ''' # 配置环境变量:export freenom_usr="",多号用&分割,示例:123@qq.com&abc@163.com # 配置环境变量:export freenom_psd="",账号对应密码同样用&分割,示例:miam1&mima2 # 密码含&的,设置export change_split="",示例:export change_split=","代表用逗号分割 # V20231a import requests import re,os,time,random try: from notify import send except: print("upload notify failed") # 没有设置环境变量可以在此处直接填写freenom用户名,多号用&分割,示例:'123@qq.com&abc@163.com' username = '' # 没有设置环境变量可以在此处直接填写freenom密码,账号对应密码同样用&分割,示例:'psd1&psd2' password = '' # 密码含&的,设置echa_split = '' ,示例:cha_split = ','代表用逗号分割 cha_split = '' # 登录url LOGIN_URL = 'https://my.freenom.com/dologin.php' # 域名状态url DOMAIN_STATUS_URL = 'https://my.freenom.com/domains.php?a=renewals' # 续期url RENEW_DOMAIN_URL = 'https://my.freenom.com/domains.php?submitrenewals=true' # 登录匹配 token_ptn = re.compile('name="token" value="(.*?)"', re.I) domain_info_ptn = re.compile( r'(.*?)[^<]+[^<]+.*?', re.I) login_status_ptn = re.compile('Logout', re.I) sess = requests.Session() sess.headers.update({ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/103.0.5060.134 Safari/537.36' }) sess.headers.update({ 'content-type': 'application/x-www-form-urlencoded', 'referer': 'https://my.freenom.com/clientarea.php' }) # 获取用户列表 def get_usr(): # 先检测环境变量 if "freenom_usr" in os.environ: # 配置环境变量:export FREENOM_USR="",多号用&分割 usr_list = os.environ["freenom_usr"].split("&") return usr_list # 从脚本内获取 elif username: usr_list = username.split('&') return usr_list # 都没有 print('Pls config export OR fill in username.') send('未在环境变量或脚本中找到账号信息,请手动添加') exit(-1) # 获取密码 def get_psd(): if "freenom_psd" in os.environ: if "change_split" in os.environ: psd_list = os.environ["freenom_psd"].split(os.environ["change_split"]) return psd_list else: # 配置环境变量:export FREENOM_PSD="",多号用&分割 psd_list = os.environ["freenom_psd"].split("&") return psd_list # 从脚本内获取 elif password: if cha_split: psd_list = password.split(cha_split) return psd_list else: psd_list = password.split('&') return psd_list # 都没有 print('Pls config export OR fill in password.') send('未在环境变量或脚本中找到密码信息,请手动添加') exit(-1) # start def main(usr,psd): try: # 异常捕捉 r = sess.post(LOGIN_URL, data={'username': usr, 'password': psd}) if r.status_code != 200: print('Can not login. Pls check network.') send('登录失败,', '请检查网络') return # 查看域名状态 sess.headers.update({'referer': 'https://my.freenom.com/clientarea.php'}) r = sess.get(DOMAIN_STATUS_URL) except: print('Network failed.') send('连接中断,', '请检查网络是否正常') return # 确认登录状态 if not re.search(login_status_ptn, r.text): print('login failed, retry') send('登录失败,', '请检查账号有效性') return # 获取token page_token = re.search(token_ptn, r.text) if not page_token: print('page_token missed') send('连接中断,', '请检查网络是否正常') return token = page_token.group(1) # 获取域名列表 domains = re.findall(domain_info_ptn, r.text) domains_list = [] renew_domains_succeed = [] renew_domains_failed = [] # 域名续期 for domain, days, renewal_id in domains: day_s = int(days) domains_list.append(f'域名:{domain}还有{day_s}天到期~') if day_s < 14: # 避免频繁操作 time.sleep(6) sess.headers.update({ 'referer': f'https://my.freenom.com/domains.php?a=renewdomain&domain={renewal_id}', 'content-type': 'application/x-www-form-urlencoded' }) try: r = sess.post(RENEW_DOMAIN_URL, data={ 'token': token, 'renewalid': renewal_id, f'renewalperiod[{renewal_id}]': '12M', 'paymentmethod': 'credit' }) except: print('Network failed.') send('连接中断,', '请检查网络是否正常') renew_domains_failed.append(domain) continue if r.text.find('Order Confirmation') != -1: renew_domains_succeed.append(domain) else: renew_domains_failed.append(domain) # 输出结果并推送通知 print(domains_list, renew_domains_succeed, renew_domains_failed) if renew_domains_failed: send(f'注意!!!您有{len(renew_domains_failed)}个域名续期失败,请及时手动操作确认!', f'续期失败的域名:{renew_domains_failed}') else: if renew_domains_succeed: send(f'账号{usr}共有{len(domains_list)}个域名:\n{domains_list}', f'域名: {renew_domains_succeed}续期成功!') else: send('恭喜,两周内没有需要续期的域名', f'账号{usr}共有{len(domains_list)}个域名:\n{domains_list}') return if __name__ == '__main__': usrs = get_usr() psds = get_psd() if len(usrs) != len(psds): print('Can not metch. Pls check export') send('账号密码数量不匹配,请检查变量, ' , '密码含&的添加change_split变量或更改密码') exit(-1) print(f'--------共{len(usrs)}个账号--------\n') for i in range(len(usrs)): print(f'***第{i + 1}个账号: {usrs[i]} ***\n') # 随机暂停几秒,错峰使用 time.sleep(random.randint(1,30)) main(usrs[i], psds[i])