阿里云域名+DDNS API實(shí)現(xiàn)動(dòng)態(tài)域名

由于家用寬帶都是動(dòng)態(tài)IP,所以想在外面訪問家里的設(shè)備就需要?jiǎng)討B(tài)域名洼裤,像花生殼這類的動(dòng)態(tài)域名要么收費(fèi)要么限制很多,用起來很不爽。下面介紹阿里云域名+DDNS API實(shí)現(xiàn)域名自動(dòng)更新离斩。

實(shí)現(xiàn)條件:

  1. 要有公網(wǎng)地址,電信用戶打10000瘪匿,聯(lián)通用戶打10010跛梗,移動(dòng)用戶洗洗睡吧,不要想太多
  2. 買個(gè)阿里云的域名棋弥,找個(gè)便宜的買核偿,我們只需要自己訪問,好記就行顽染,十來塊錢一年的多的是
  3. 能執(zhí)行python的電腦漾岳、NAS、軟路由器都行粉寞,黑白群暉是肯定沒問題尼荆。

阿里云的API本身不難用,難就難在簽名上唧垦,下面的代碼只要改動(dòng)下面幾個(gè)關(guān)鍵參數(shù)就可以用了耀找。
AccessKeyId = "你的AccessKeyId"
AccessKeySecret = "你的AccessKeySecret"
RR = "你的RR"
DomainName = "你的域名"
AccessKeyId和AccessKeySecret在你的阿里云賬號(hào)里可以直接申請(qǐng),具體操作請(qǐng)找度娘业崖。關(guān)于RR野芒、DomainName和A記錄,剛接觸的人可能有點(diǎn)暈双炕。這里舉個(gè)例子狞悲,你的域名全稱是my.abc.com,那么RR就是my,DomainName就是abc.com,A記錄就是域名對(duì)應(yīng)的IP地址妇斤。
把代碼保存為.py文件摇锋,然后計(jì)劃任務(wù)定時(shí)執(zhí)行,執(zhí)行頻率不要太頻繁站超,設(shè)定10分鐘左右就行荸恕,太頻繁可能會(huì)被服務(wù)器限制。
代碼在python3.8下測試通過

# coding=utf-8
'''
本例全部使用python3自帶庫死相,無需額外安裝第三方庫融求,方便小白使用
'''
import base64  # 編碼
import datetime  # 日期時(shí)間
import hmac  # 哈希算法
import re  # 正則表達(dá)式
import time # 時(shí)間
import urllib.parse  # url地址解析
import urllib.request  # url請(qǐng)求處理
import xml.dom.minidom # XML處理
from uuid import uuid1  #  通用唯一識(shí)別碼

AccessKeyId = "你的AccessKeyId"
AccessKeySecret = "你的AccessKeySecret"
APIServer = "http://alidns.aliyuncs.com"  # API服務(wù)器地址,不需要改動(dòng)
RR = "你的RR"  # 對(duì)應(yīng)的A記錄
DomainName = "你的域名"  # 你的域名
count = 0
c_para = {"Format": "XML", "Version": "2015-01-09", "SignatureMethod": "HMAC-SHA1",
          "Timestamp": datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ'), "SignatureVersion": "1.0",
          "SignatureNonce": str(uuid1()), "AccessKeyId": AccessKeyId}


# 公共參數(shù)設(shè)置算撮,每個(gè)DDNS API都需要的參數(shù)生宛,不需要改動(dòng)县昂。


def perencode(strs):  # 字符編碼函數(shù)

    res = urllib.parse.quote(strs.encode("utf_8"))  # 對(duì)字符串進(jìn)行 utf-8 編碼,然后進(jìn)行URL格式編碼
    res = res.replace("+", "%20").replace("*", "%2A").replace("%7E", "~")  # 按簽名要求進(jìn)行替換字符
    return res

def signature(p_para, c_para, AccessKeySecret):  # 簽名函數(shù)

    reqstr = sorted({**p_para, **c_para}.items(), key=lambda x: x[0])  # 按關(guān)鍵字對(duì)合并后的字典進(jìn)行排序
    signaturestr = ""
    for i in reqstr:
        signaturestr = signaturestr + perencode(i[0]) + "=" + perencode(i[1]) + "&"
        # 對(duì)排序后的字典進(jìn)行轉(zhuǎn)碼并重新拼接:a=a&b=b&c=c 格式
    signaturestr = signaturestr.strip("&")  # 去除首尾的 &號(hào)
    signaturestr = "GET&%2F&" + perencode(signaturestr)
    n = hmac.new((AccessKeySecret + "&").encode("utf-8"), signaturestr.encode("utf-8"), "sha1").digest()  # 計(jì)算哈希值
    signaturestr = base64.b64encode(n)  # base64編碼陷舅,bytes類型
    return signaturestr.decode()  # 返回解碼后的字符串倒彰,str類型

def urlstr(c_para, p_para, APIServer):  # 最終請(qǐng)求地址構(gòu)造函數(shù)

    dic = {**p_para, **c_para}
    urlstr = ""
    for i in dic.items():
        urlstr = urlstr + i[0] + "=" + i[1] + "&"
    urlstr = APIServer + "?" + urlstr + "Signature=" + str(signature(p_para, c_para, AccessKeySecret))
    # 對(duì)請(qǐng)求參數(shù)進(jìn)行拼接,形成最終URL地址莱睁,就可以在瀏覽器直接訪問了
    return urlstr

def get_ip():  # 獲取當(dāng)前公網(wǎng)IP地址
    getip_url = "http://www.net.cn/static/customercare/yourip.asp"  # 通過萬網(wǎng)獲取
    reqs = urllib.request.Request(getip_url)
    resp = urllib.request.urlopen(reqs)
    data = resp.read()
    ip = re.findall(r"\d+\.+\d+\.+\d+\.+\d+", data.decode("utf-8", "ignore"))
    return ip


def get_record(RR, DomainName):  # 取得對(duì)應(yīng)A記錄的IP地址

    # DomainName   你想獲取記錄的域名
    # RR你想返回域名的哪個(gè)記錄
    # 域名結(jié)構(gòu):RR.DomainName待讳,如域名為:www.abc.com ;RR=www,DomainName=abc.com
    p_para = {"Action": "DescribeDomainRecords", "DomainName": DomainName}
    # DescribeDomainRecords動(dòng)作的私有參數(shù)設(shè)置
    url = urlstr(c_para, p_para, APIServer)
    try:  # 捕獲可能出現(xiàn)的錯(cuò)誤
        reqs = urllib.request.Request(url)
        resp = urllib.request.urlopen(reqs)
    except Exception as e:  # 對(duì)應(yīng)錯(cuò)誤的處理方式
        return "Error", e.reason  # 返回"Error"(Error是自己定義的錯(cuò)誤代碼)仰剿,并返回錯(cuò)誤原因
    else:  # 沒有錯(cuò)誤執(zhí)行
        data = resp.read().decode('utf-8')
        xmldoc = xml.dom.minidom.parseString(data)
        rootNode = xmldoc.documentElement
        if rootNode.nodeName == "Error":
            return "Error", data
        DomainRecords = rootNode.getElementsByTagName('DomainRecords')
        Record = DomainRecords[0].getElementsByTagName("Record")
        RecordId = Record[0].getElementsByTagName("RecordId")[0].childNodes[0].nodeValue
        IP = Record[0].getElementsByTagName("Value")[0].childNodes[0].nodeValue
        return RecordId, IP


def update_record(RR, DomainName):  # 更新應(yīng)A記錄的IP地址
    myrecord = get_record(RR, DomainName)
    if myrecord[0] == "Error":
        print("獲取域名信息失敶吹:", myrecord[1])
        return "Error"
    myip = get_ip()

    if myip == myrecord[1]:
        print("IP地址相同,無需更新酥馍。")
    else:
        print("A記錄地址:", myrecord[1], "當(dāng)前IP地址:", myip)
        p_para = {"Action": "UpdateDomainRecord", "RR": RR, "RecordId": myrecord[0], "Type": "A", "Value": myip}
        # UpdateDomainRecord動(dòng)作的私有參數(shù)設(shè)置
        url = urlstr(c_para, p_para, APIServer)

        try:  # 捕獲可能出現(xiàn)的錯(cuò)誤
            reqs = urllib.request.Request(url)
            resp = urllib.request.urlopen(reqs)
        except Exception as e:  # 錯(cuò)誤的處理方式
            print("更新地址失敗:", e.reason)
            return
        else:  # 沒有錯(cuò)誤執(zhí)行
            print("更新地址成功辩昆!")
            return

while update_record(RR, DomainName) == "Error":
    time.sleep(5)
    update_record(RR, DomainName) 
    count += 1
    if count == 5:
        print("更新失敗阅酪,請(qǐng)檢查看錯(cuò)誤信息旨袒!")
        break
# 有時(shí)訪問API會(huì)出現(xiàn)無法預(yù)料的錯(cuò)誤造成更新失敗。出現(xiàn)錯(cuò)誤就再次嘗試更新术辐,每次延遲5秒砚尽,5次不成功就退出程序。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辉词,一起剝皮案震驚了整個(gè)濱河市必孤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瑞躺,老刑警劉巖敷搪,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異幢哨,居然都是意外死亡赡勘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門捞镰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闸与,“玉大人,你說我怎么就攤上這事岸售〖#” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵凸丸,是天一觀的道長拷邢。 經(jīng)常有香客問我,道長屎慢,這世上最難降的妖魔是什么解孙? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任坑填,我火速辦了婚禮,結(jié)果婚禮上弛姜,老公的妹妹穿的比我還像新娘脐瑰。我一直安慰自己,他們只是感情好廷臼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布苍在。 她就那樣靜靜地躺著,像睡著了一般荠商。 火紅的嫁衣襯著肌膚如雪寂恬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天莱没,我揣著相機(jī)與錄音初肉,去河邊找鬼。 笑死饰躲,一個(gè)胖子當(dāng)著我的面吹牛牙咏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嘹裂,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼妄壶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了寄狼?” 一聲冷哼從身側(cè)響起丁寄,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泊愧,沒想到半個(gè)月后伊磺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡删咱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年屑埋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腋腮。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雀彼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出即寡,到底是詐尸還是另有隱情徊哑,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布聪富,位于F島的核電站莺丑,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜梢莽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一萧豆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧昏名,春花似錦涮雷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仑扑,卻和暖如春览爵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背镇饮。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工蜓竹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人储藐。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓俱济,卻偏偏與公主長得像,于是被迫代替她去往敵國和親邑茄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子姨蝴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 打印機(jī)知識(shí)簡介 打印機(jī)是計(jì)算機(jī)的輸出設(shè)備之一俊啼,用于將文本肺缕、圖片等內(nèi)容打印在相關(guān)介質(zhì)上。衡量打印機(jī)好壞的指標(biāo)有三項(xiàng):...
    多多多_91fe閱讀 1,147評(píng)論 0 0
  • 作者:黃文冰五年級(jí)一班 前言: 現(xiàn)在授帕,我們身處于二十一世紀(jì)的中國同木,文具也是越來越多樣化,...
    黃_文_冰_閱讀 6,045評(píng)論 1 1
  • 專業(yè)考題類型管理運(yùn)行工作負(fù)責(zé)人一般作業(yè)考題內(nèi)容選項(xiàng)A選項(xiàng)B選項(xiàng)C選項(xiàng)D選項(xiàng)E選項(xiàng)F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 8,988評(píng)論 0 13
  • 一跛十、活動(dòng)前準(zhǔn)備 1彤路、 提前一周周四做出活動(dòng)海報(bào)——書童萌萌 2、 提前一周周四到活動(dòng)當(dāng)天(周三)芥映,每天轉(zhuǎn)發(fā)一次活動(dòng)...
    花麗林閱讀 191評(píng)論 0 1
  • 敬愛的李老師 智慧的馬教授 親愛的家人們們大家晚上好奈偏,我是侯維山(侯總)的人 來自濱州鑫山力機(jī)械的 郝合柱 今...
    7b5a5d9c70e6閱讀 118評(píng)論 0 1