亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

利用Python+阿里云實(shí)現(xiàn)DDNS動(dòng)態(tài)域名解析的方法

 更新時(shí)間:2019年04月01日 15:45:22   作者:mgsky1  
這篇文章主要介紹了利用Python+阿里云實(shí)現(xiàn)DDNS動(dòng)態(tài)域名解析的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

引子

我想大家應(yīng)該都很熟悉DNS了,這回在DNS前面加了一個(gè)D又變成了什么呢?這個(gè)D就是Dynamic(動(dòng)態(tài)),也就是說(shuō),按照傳統(tǒng),一個(gè)域名所對(duì)應(yīng)的IP地址應(yīng)該是定死的,而使用了DDNS后,域名所對(duì)應(yīng)的IP是可以動(dòng)態(tài)變化的。那這個(gè)有什么用呢?
比如,在家里的路由器上連著一個(gè)raspberry pi(樹(shù)莓派),上面跑著幾個(gè)網(wǎng)站,我應(yīng)該如和在外網(wǎng)環(huán)境下訪問(wèn)網(wǎng)站、登陸樹(shù)莓派的SSH呢?

還有,家里的NAS(全稱Network Attach Storage 網(wǎng)絡(luò)附屬存儲(chǔ),可以理解為私有的百度網(wǎng)盤(pán))上存儲(chǔ)著大量的視頻、照片,如何在外網(wǎng)環(huán)境下和朋友分享呢?

這時(shí),就要靠DDNS了!它會(huì)動(dòng)態(tài)偵運(yùn)營(yíng)商分配給你的IP變化,并映射到域名上,這時(shí)就可以用域名來(lái)訪問(wèn)家庭環(huán)境中的內(nèi)容了~

哈!有了域名,走遍天下都不怕有木有

實(shí)現(xiàn)效果(因?yàn)槲乙呀?jīng)更新過(guò)了,所以它提示IP地址已存在,阿里云是不允許同一個(gè)IP重復(fù)更新的)

 

本地:

 

使用DDNS后,在外網(wǎng)環(huán)境下:

 

注:

這篇帖子適用于家庭寬帶的IP是公網(wǎng)IP的小伙伴,但是注意,這種公網(wǎng)IP是臨時(shí)的,會(huì)不定時(shí)進(jìn)更改。判斷方法很簡(jiǎn)單:先去百度搜索IP,查到自己的IP地址;接著本地開(kāi)一個(gè)網(wǎng)站,比如在Windows下直接啟動(dòng)IIS,Linux下安裝一個(gè)Apache或者Nginx啟動(dòng),使用它們的默認(rèn)頁(yè)面;然后在路由器上設(shè)置好轉(zhuǎn)發(fā)規(guī)則,公網(wǎng)IP的網(wǎng)絡(luò)訪問(wèn)端口最好不要用80,80端口可能被運(yùn)營(yíng)商封了;最后利用前面查到的公網(wǎng)IP+端口號(hào)訪問(wèn)一下,看看能不能顯示內(nèi)網(wǎng)上的頁(yè)面,如果可以,恭喜你!

本文涉及到的技術(shù)點(diǎn)會(huì)比較多,比如爬蟲(chóng)啊,設(shè)計(jì)模式啊,函數(shù)修飾符啊等等,可以算是一個(gè)綜合運(yùn)用了吧~

實(shí)現(xiàn)思路

前面引文已經(jīng)說(shuō)的很清楚了,就是探測(cè)家庭寬帶公網(wǎng)IP的變化,然后利用我們的程序?qū)⑦@個(gè)IP更新到它所綁定的二級(jí)域名上~
綜上,我的思路是這樣的:
1、利用Python去網(wǎng)上爬取自己真實(shí)的IP地址
2、利用阿里云所提供的接口更新IP

前期準(zhǔn)備

1、一個(gè)域名(國(guó)內(nèi)需要備案,港澳臺(tái)和國(guó)外聽(tīng)說(shuō)是不要的,我也沒(méi)嘗試過(guò))
2、將域名的解析設(shè)置到阿里云的云解析上
3、為我們的DDNS創(chuàng)建一個(gè)二級(jí)域名(例如 ddns.expamle.com)
4、安裝阿里云Python SDK(具體教程可以去阿里云上找
5、建議先去閱讀一下Python SDK的使用示例
6、約定:所有的API請(qǐng)求都返回JSON格式,所以要使用Python的JSON模塊進(jìn)行解析

環(huán)境版本

1、Python 3.6
2、網(wǎng)頁(yè)解析利用BeautifulSoup 4
3、阿里的云解析API和Python SDK直接使用官方最新版本即可

實(shí)現(xiàn)步驟

項(xiàng)目結(jié)構(gòu)

 

注:

AcsClientSingleton.py => 阿里云AcsClient單實(shí)例類(lèi)

CommonRequestSingleton.py => 阿里云CommonRequest的單實(shí)例類(lèi),獲取阿里云Common Request請(qǐng)求類(lèi)

DDNS.py => 主程序

IpGetter.py =>獲取家庭寬帶實(shí)際的公網(wǎng)IP

Utils.py => 工具類(lèi)

爬IP

首當(dāng)其沖的就是要獲得我們實(shí)際的IP地址,推薦ip138.com

你看到的頁(yè)面是這樣的:

 

畫(huà)紅框的部分是一個(gè)iframe

 

其中的URL是一直會(huì)變化的,所以第一步是要獲取這個(gè)URL,我這里用到的解析框架是BeautifulSoup,感覺(jué)用Scrapy有點(diǎn)大材小用了

#獲得IP檢測(cè)的網(wǎng)頁(yè)URL
def getIpPage():
 url = "http://www.ip138.com/"
 response = urllib.request.urlopen(url)
 html = response.read().decode("gb2312")
 soup = BeautifulSoup(html, "lxml")
 _iframe = soup.body.iframe
 return _iframe["src"]

獲取到檢測(cè)IP地址的URL后,我們可以觀察一下網(wǎng)頁(yè)結(jié)構(gòu)

 

發(fā)現(xiàn),我們只需要獲取到center標(biāo)簽的內(nèi)容,然后用正則提取出IP即可

#獲取IP地址
def getRealIp(url):
 response = urllib.request.urlopen(url)
 html = response.read().decode("gb2312")
 pattern = r"(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)"
 matchs = re.search(pattern,html)
 ip_addr = ""
 for i in range(1,5):
  ip_addr += matchs.group(i) + "."
 return ip_addr[:-1]

然后我們爬的工作就完成了,可以將這個(gè)獲取IP的過(guò)程進(jìn)行封裝,放進(jìn)工具類(lèi)里

查文檔

阿里云云解析API文檔

我們需要用到的是UpdateDomainRecord這個(gè)Action。

可以觀察一下它的請(qǐng)求參數(shù)

 

在阿里的請(qǐng)求中,有一個(gè)公共參數(shù)(上面沒(méi)有提及),里面有一個(gè)簽名,這個(gè)簽名雖然官方提供了簽名生成的算法,不過(guò)如果自己實(shí)現(xiàn)很容易出錯(cuò),所以我們使用它的Python SDK。在簽名中,有一個(gè)至關(guān)重要的是AccessKey,AccessKey的生成可以在管理控制臺(tái)的AccessKeys模塊獲取

 

生成之后一定要保管好這個(gè)密鑰哦!?。。?!

由于云解析官方并沒(méi)有提供對(duì)應(yīng)的SDK模塊,只提供了API,不過(guò)我們可以利用SDK中的CommonRequest對(duì)象來(lái)進(jìn)行API操作。不知道各位有木有發(fā)現(xiàn)在更新域名解析記錄的請(qǐng)求參數(shù)中有一個(gè)RecordId,這個(gè)RecordId要利用DescribeDomainRecords這個(gè)Action來(lái)獲取。

如果每次請(qǐng)求都要使用CommonRequest對(duì)象,這樣難免會(huì)造成一定的內(nèi)存浪費(fèi),所以使用面向?qū)ο笤O(shè)計(jì)模式中的單例模式進(jìn)行優(yōu)化。

class CommonRequestSing:
 #私有類(lèi)變量
 __request = None

 #該修飾符將實(shí)例方法變成類(lèi)方法
 #,因?yàn)轭?lèi)方法無(wú)法操作私有的類(lèi)變量,所以使用實(shí)例方法進(jìn)行操作,再進(jìn)行轉(zhuǎn)換為類(lèi)方法
 @classmethod
 def getInstance(self):
  if self.__request is None:
   self.__request = CommonRequest()
  return self.__request

同時(shí),在構(gòu)造請(qǐng)求式,也會(huì)用到AcsClient對(duì)象,也可使用單例模式優(yōu)化

class AcsClientSing:
 __client = None
 @classmethod
 def getInstance(self):
  if self.__client is None:
   self.__client = AcsClient('Your_AccessKeyId', 'Your_AccessKeySecret', 'cn-hangzhou')
  return self.__client

這里用到了函數(shù)修飾符@classmethod,主要功能是將實(shí)例方法轉(zhuǎn)換為類(lèi)方法。

這兩個(gè)單實(shí)例都可封裝進(jìn)工具類(lèi)中,直接調(diào)用工具類(lèi)獲取實(shí)例就可以了,代碼會(huì)更美觀一些。

獲取RecordID

利用DescribeDomainRecords 這個(gè)Action來(lái)獲得。

#獲取二級(jí)域名的RecordId
 def getRecordId(domain):
  client = Utils.getAcsClient()
  request = Utils.getCommonRequest()
  request.set_domain('alidns.aliyuncs.com')
  request.set_version('2015-01-09')
  request.set_action_name('DescribeDomainRecords')
  request.add_query_param('DomainName', 'Your_DomainName eg.example.com')
  response = client.do_action_with_exception(request)
  jsonObj = json.loads(response.decode("UTF-8"))
  records = jsonObj["DomainRecords"]["Record"]
  for each in records:
   if each["RR"] == domain:
    return each["RecordId"]

更新解析記錄IP,DDNS邏輯核心

def DDNS():
 client = Utils.getAcsClient()
 recordId = Utils.getRecordId('ddns')
 ip = Utils.getRealIP()
 request = Utils.getCommonRequest()
 request.set_domain('alidns.aliyuncs.com')
 request.set_version('2015-01-09')
 request.set_action_name('UpdateDomainRecord')
 request.add_query_param('RecordId', recordId)
 request.add_query_param('RR', 'ddns')
 request.add_query_param('Type', 'A')
 request.add_query_param('Value', ip)
 response = client.do_action_with_exception(request)
 return response

if __name__ == "__main__":
 try:
  result = DDNS()
  print("成功!")
 except (ServerException,ClientException) as reason:
  print("失敗!原因?yàn)?)
  print(reason.get_error_msg())

至此結(jié)束~然后設(shè)置好路由器端口映射,這時(shí)候你就可以使用ddns.example.com:XXX來(lái)進(jìn)行訪問(wèn)設(shè)置在家庭網(wǎng)絡(luò)中的資源了~
然后可以將這個(gè)Python代碼設(shè)置為定時(shí)任務(wù),比如每天執(zhí)行一次,或者根據(jù)運(yùn)營(yíng)商的IP變化策略調(diào)整~

源碼(最新):https://github.com/mgsky1/DDNS

源碼(結(jié)構(gòu)與文章一樣的):點(diǎn)擊這里

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論