Freenom 域名自动续期。Freenom domain name renews automatically.
实战
腾讯云函数python
SunYufei/freenom: Freenom 域名自动续期 Python 版本 (github.com)
GitHub Action
用做CI
工具,修改下用在腾讯云函数上。
创建腾讯云函数
直接访问腾讯云函数控制台创建云函数: https://console.cloud.tencent.com/scf/list-create
1 2 3 4
| 自定义创建 事件函数 代码部署 Python3.6
|
依赖安装
- 在“函数管理”页面中,选择函数代码 > 代码编辑,查看并编辑函数。
- 在 IDE 顶部的菜单栏终端中选择新终端,打开终端窗口。
- 在终端中执行如下命令,安装依赖库 :
1 2 3 4 5
| cd src # 依赖库需要安装在与函数入口文件同一级的目录下,即需要进入`src`目录后再执行依赖安装操作。 pip3 install requests -t . python -m pip install --upgrade requests pyaes -t . pip install python-telegram-bot --upgrade -t . pip3 install python-telegram-bot --upgrade -t .
|
configuration
env
1 2 3 4
| FREENOM_USERNAME=username1,username2... FREENOM_PASSWORD=password1,password2... BOT_API CHAT_ID
|
cron
index.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| # -*- coding: utf8 -*-
import os from freenom import FreeNom import time import re import requests from urllib import parse
class FreenomDomainNameRenewsAutomaticallys():
tg_text = '' # 打印输出当前ip地址 def print_my_ip(self): api_url = 'https://api.ipify.org/' try: res = requests.get(url=api_url) res.raise_for_status() res.encoding = 'utf-8' self.tg_text = self.tg_text + '当前使用 ip 地址:' + res.text.replace('.', ',') + '\n' print('当前使用 ip 地址:' + res.text) except Exception as e: self.tg_text = self.tg_text + '获取当前 ip 地址失败:' + str(e) + '\n' print('获取当前 ip 地址失败:' + str(e))
# TG推送 def post(self, bot_api, chat_id, text): print('开始推送') headers = { 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36'} text = parse.quote(text) # 修改为自己的bot api token post_url = 'https://api.telegram.org/bot{}/sendMessage' \ '?parse_mode=MarkdownV2&chat_id={}&text={}'.format(bot_api, chat_id, text) try: requests.get(post_url, headers=headers) print('推送成功') except Exception: print("推送失败") time.sleep(3) # 避免推送死循环 try: requests.get(post_url, headers=headers) except Exception: pass
def domainNameRenewsAutomaticallys(self, usernames, passwords, bot_api, chat_id): # 分割用户名和密码为列表 user_list = usernames.split(',') passwd_list = passwords.split(',') if not usernames or not passwords: self.tg_text = self.tg_text + '未检测到用户名或密码,请检查环境变量是否设置正确!\n' print('未检测到用户名或密码,请检查环境变量是否设置正确!') elif len(user_list) != len(passwd_list): self.tg_text = self.tg_text + '用户名与密码个数不匹配,请检查环境变量设置是否错漏!\n' print('用户名与密码个数不匹配,请检查环境变量设置是否错漏!') else: self.print_my_ip() self.tg_text = self.tg_text + '共检测到{}个帐户,开始域名自动续期\n'.format(len(user_list)) print('共检测到', len(user_list), '个帐户,开始域名自动续期') print('*' * 30) # 依次登录帐户获取积分,出现错误时不中断程序继续尝试下一个帐户 for i in range(len(user_list)): try: t='' instance = FreeNom(user_list[i], passwd_list[i]) t=instance.renew() self.tg_text=self.tg_text+t # print(self.tg_text) i=i+1 except Exception as e: self.tg_text = self.tg_text + '程序执行异常:' print('程序执行异常:' + str(e)) print('*' * 30) continue self.tg_text = self.tg_text.replace('.', ',') + '\n程序执行完毕,域名自动续期过程结束' print('程序执行完毕,域名自动续期过程结束') print(self.tg_text) self.post(bot_api, chat_id, self.tg_text)
def main_handler(event, context): usernames = os.environ['username'] passwords = os.environ['password'] bot_api = os.environ['BOT_API'] chat_id = os.environ['CHAT_ID'] f = FreenomDomainNameRenewsAutomaticallys() f.domainNameRenewsAutomaticallys(usernames, passwords, bot_api, chat_id) return("Hello World")
if __name__ == '__main__': main_handler("","")
|
freedom.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| import re
import requests
# 登录地址 LOGIN_URL = 'https://my.freenom.com/dologin.php'
# 域名状态地址 DOMAIN_STATUS_URL = 'https://my.freenom.com/domains.php?a=renewals'
# 域名续期地址 RENEW_DOMAIN_URL = 'https://my.freenom.com/domains.php?submitrenewals=true'
# token 正则 token_ptn = re.compile('name="token" value="(.*?)"', re.I)
# 域名信息正则 domain_info_ptn = re.compile( r'<tr><td>(.*?)</td><td>[^<]+</td><td>[^<]+<span class="[^<]+>(\d+?).Days</span>[^&]+&domain=(\d+?)">.*?</tr>', re.I)
# 登录状态正则 login_status_ptn = re.compile('<a href="logout.php">Logout</a>', re.I)
class FreeNom: def __init__(self, username: str, password: str): self._u = username self._p = password
self._s = requests.Session() self._s.headers.update({ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/79.0.3945.130 Safari/537.36' })
def _login(self) -> bool: self._s.headers.update({ 'content-type': 'application/x-www-form-urlencoded', 'referer': 'https://my.freenom.com/clientarea.php' }) r = self._s.post(LOGIN_URL, data={'username': self._u, 'password': self._p}) return r.status_code == 200
def renew(self): # login ok = self._login() if not ok: print('login failed') return
# check domain status self._s.headers.update({'referer': 'https://my.freenom.com/clientarea.php'}) r = self._s.get(DOMAIN_STATUS_URL)
# login status check if not re.search(login_status_ptn, r.text): print('get login status failed') return
# page token match = re.search(token_ptn, r.text) if not match: print('get page token failed') return token = match.group(1)
# domains domains = re.findall(domain_info_ptn, r.text)
# renew domains text='' for domain, days, renewal_id in domains: days = int(days) if days < 14: self._s.headers.update({ 'referer': f'https://my.freenom.com/domains.php?a=renewdomain&domain={renewal_id}', 'content-type': 'application/x-www-form-urlencoded' }) r = self._s.post(RENEW_DOMAIN_URL, data={ 'token': token, 'renewalid': renewal_id, f'renewalperiod[{renewal_id}]': '12M', 'paymentmethod': 'credit' }) print(domain, '续期成功' if r.text.find('Order Confirmation') != -1 else '续期失败') # domain=domain.replace(",", "."); # print(f'{domain} 还有 {days} 天续期') text+=f'{domain} 还有 {days} 天续期\n' # print(text) return text
|
结果
通过腾讯云函数(SCF)部署php版
使用腾讯云函数
luolongfei/freenom: Freenom 域名自动续期。Freenom domain name renews automatically. (github.com)
1、下载 SCF 版本的压缩包
此版本为特别版,支持通过腾讯云函数部署,并且将与主分支同步维护更新,推荐没有自己 VPS 服务器的用户使用,最新版本号为v0.3.1_scf
。下载地址: https://github.com/luolongfei/freenom/releases/download/v0.3.1_scf/freenom-0.3.1_scf.zip
下载后你将得到一个 zip 文件,将 zip 文件放到你能找到的任意目录,后面我们将以 zip 文件的形式上传到腾讯云函数。
2、创建腾讯云函数
直接访问腾讯云函数控制台创建云函数: https://console.cloud.tencent.com/scf/list-create , 按照下图所示的说明进行创建。如果无法看清图片,可访问: https://github.com/luolongfei/freenom/blob/main/resources/screenshot/scf.png 或者 https://z3.ax1x.com/2021/10/14/5lMweU.png 查看原图。
按照上图所示部署完成后,可以点击云函数的名称进入云函数管理画面,管理画面点击函数代码,然后往下翻可看到部署
与测试
按钮,点击测试
,稍等几秒钟,即可看到输出日志, 根据输出日志判断配置以及部署是否正确。
有关腾讯云函数部署的内容结束。