鱼C论坛

 找回密码
 立即注册
查看: 1451|回复: 1

[技术交流] 【转载】阿里云DDNS动态域名解析,无需SDK

[复制链接]
发表于 2021-1-18 16:11:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
找了半天的阿里云解析,论坛也有一篇,但是缺太多代码了,实在不知道怎么改,这个直接填入自己的AccessKeyID, AccessKeySecret,还有要解析的域名就可以直接用,什么都不用改,转载一下,也作为自己一个收藏
代码转自52论坛的 https://www.52pojie.cn/forum.php?mod=viewthread&tid=1296738


  1. import re, json, time, uuid, random, chardet
  2. import hmac, base64, hashlib
  3. import requests
  4. import urllib.parse, urllib.request

  5. # 轮询时间间隔
  6. TIME_INTERVAL = 5


  7. class PublicIP(object):
  8.     def __init__(self):
  9.         self.user_agent = ('Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
  10.                            'Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3776.400 QQBrowser/10.6.4212.400')
  11.         self.api_list = [
  12.             'https://202020.ip138.com/',
  13.             'https://www.ip.cn/api/index?ip=&type=0',
  14.             'http://ip.webmasterhome.cn/',
  15.             'http://ip.yqie.com/clientip.aspx',
  16.             'https://www.123cha.com/ip/',
  17.             'http://ip.chacuo.net/',
  18.         ]

  19.     def ip_query(self):
  20.         while True:
  21.             url = random.sample(self.api_list, 1)[0]
  22.             try:
  23.                 res = requests.get(url, headers={'User-Agent': self.user_agent}, timeout=5)
  24.                 encoding = chardet.detect(res.content)['encoding']
  25.                 html = res.content.decode(encoding)
  26.                 out = re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', html)
  27.                 if out != []: return out[0]
  28.             except Exception as e:
  29.                 continue


  30. class AscSigner(object):
  31.     def __init__(self, AccessKeyId, AccessKeySecret):
  32.         self.AccessKeyId = AccessKeyId
  33.         self.AccessKeySecret = AccessKeySecret

  34.     def _utc(self):
  35.         return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())

  36.     def _uuid(self):
  37.         return str(uuid.uuid4())

  38.     def _pop_standard_urlencode(self, query):
  39.         ret = query.replace('+', '%20')
  40.         ret = ret.replace('*', '%2A')
  41.         ret = ret.replace('%7E', '~')
  42.         return ret

  43.     def _common_param(self):
  44.         return {
  45.             'Format': 'JSON',
  46.             'Version': '2015-01-09',
  47.             'SignatureMethod': 'HMAC-SHA1',
  48.             'SignatureNonce': self._uuid(),
  49.             'SignatureVersion': '1.0',
  50.             'AccessKeyId': self.AccessKeyId,
  51.             'Timestamp': self._utc(),
  52.         }

  53.     def _string_to_sign(self, param):
  54.         sorted_parameters = sorted(list(param.items()), key=lambda param: param[0])
  55.         sorted_query_string = self._pop_standard_urlencode(urllib.parse.urlencode(sorted_parameters))
  56.         canonicalized_query_string = self._pop_standard_urlencode(urllib.request.pathname2url(sorted_query_string))
  57.         string_to_sign = "GET&%2F&" + canonicalized_query_string
  58.         return string_to_sign

  59.     def _sign(self, string_to_sign):
  60.         param_encode = bytes(string_to_sign, 'utf-8')
  61.         key = bytes(self.AccessKeySecret + '&', 'utf-8')
  62.         h = hmac.new(key, param_encode, hashlib.sha1)
  63.         return str(base64.encodebytes(h.digest()).strip(), "utf-8")

  64.     def get_param_and_sign(self, action_param):
  65.         common_param = self._common_param()
  66.         param = dict(common_param, **action_param)
  67.         string_to_sign = self._string_to_sign(param)
  68.         signature = self._sign(string_to_sign)
  69.         param['Signature'] = signature
  70.         url = '?' + self._pop_standard_urlencode(urllib.parse.urlencode(param))
  71.         return url


  72. class AscRequestParam(object):
  73.     def __init__(self, AccessKeyId, AccessKeySecret):
  74.         self.signer = AscSigner(AccessKeyId, AccessKeySecret)

  75.     # 获取域名列表
  76.     def get_domains_params(self):
  77.         action_param = {
  78.             'Action': 'DescribeDomains',
  79.             'PageSize': '100',
  80.         }
  81.         return self.signer.get_param_and_sign(action_param)

  82.     # 获取解析记录
  83.     def get_domain_records_params(self, domain_name):
  84.         action_param = {
  85.             'Action': 'DescribeDomainRecords',
  86.             'DomainName': domain_name,
  87.             'PageSize': '100',
  88.         }
  89.         return self.signer.get_param_and_sign(action_param)

  90.     # 修改解析记录
  91.     def update_domain_record_params(self, data):
  92.         action_param = {
  93.             'Action': 'UpdateDomainRecord',
  94.             'RR': data['RR'],
  95.             'RecordId': data['RecordId'],
  96.             'Type': data['Type'],
  97.             'Value': data['Value'],
  98.         }
  99.         return self.signer.get_param_and_sign(action_param)

  100.     # 获取解析记录信息
  101.     def get_domain_record_info_params(self, RecordId):
  102.         action_param = {
  103.             'Action': 'DescribeDomainRecordInfo',
  104.             'RecordId': RecordId,
  105.         }
  106.         return self.signer.get_param_and_sign(action_param)


  107. class AscClient(object):
  108.     def __init__(self, AccessKeyId, AccessKeySecret):
  109.         self.ip = PublicIP()
  110.         self.client = AscRequestParam(AccessKeyId, AccessKeySecret)
  111.         self.api = 'https://alidns.aliyuncs.com/'

  112.     def _request(self, params):
  113.         res = requests.get(self.api + params)
  114.         return json.loads(res.content.decode('utf-8'))

  115.     def _wait(self):
  116.         timecount = TIME_INTERVAL
  117.         while timecount >= 0:
  118.             print(f"\r再次检测倒计时:{timecount}秒...", end="", flush=True)
  119.             timecount = timecount - 1
  120.             time.sleep(1)
  121.         print('\n\n', end="", flush=True)

  122.     def update_domain_record(self, record):
  123.         ip = self.ip.ip_query()
  124.         print(f'公网IP:{ip},')
  125.         if ip == record['Value']:
  126.             print('公网IP和解析IP相同,无需更新')
  127.             return
  128.         record['Value'] = ip
  129.         params = self.client.update_domain_record_params(record)
  130.         self._request(params)
  131.         print('解析完成')

  132.     def get_domain_records(self, RR, domain_name):
  133.         params = self.client.get_domain_records_params(domain_name)
  134.         res = self._request(params)
  135.         TotalCount = int(res['TotalCount'])
  136.         for i in res['DomainRecords']['Record']:
  137.             if i['RR'] == RR:
  138.                 return i
  139.         return None

  140.     def get_domains(self):
  141.         params = self.client.get_domains_params()
  142.         res = self._request(params)
  143.         domain_list = []
  144.         for i in res['Domains']['Domain']:
  145.             domain_list.append(i['DomainName'])
  146.         return int(res['TotalCount']), domain_list

  147.     def start(self, RR, domain_name):
  148.         while True:
  149.             count, domains = self.get_domains()
  150.             if count <= 0 or not domain_name in domains:
  151.                 print('没有此域名')
  152.                 return
  153.             record = self.get_domain_records(RR, domain_name)
  154.             if not record:
  155.                 print(f'没有找到{RR}的解析记录')
  156.                 return
  157.             if not record['Type'] == 'A':
  158.                 print('暂时只支持解析A记录')
  159.                 return
  160.             if record['Status'] == 'DISABLE':
  161.                 print('此记录已被禁用,请启用后再试')
  162.                 return
  163.             self.update_domain_record(record)
  164.             self._wait()


  165. if __name__ == '__main__':
  166.     # 换成你自己的AccessKeyID, AccessKeySecret
  167.     a = AscClient('**********', '**********************')

  168.     # 如果需要解析 www.baidu.com,填入 www 和 baidu.com
  169.     # 如果需要解析 baidu.com  填入 @ 和 baidu.com
  170.     a.start('test', 'mydomain.net')
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-1-18 16:14:11 | 显示全部楼层
66666666666666666666666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 16:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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