这是个通过监控本地当前外网 IP 变化,并设置域名解析到当前 IP 的 python 脚本。

运行环境准备:
1.python2.7
2.主机屋域名
3.你的 IP 没有被运营商 NAT(关于这点请自行百度)
4.路由器已设置 DMZ 主机为当前机器

确认环境后我们看这个脚本,先导入用到的模块:

# -*-coding:utf-8-*-
__author__ = "orion-c.win"
import os,time,re,json
import urllib
import urllib2
import cookielib

其中 re,json,cookielib 都是需要我们 pip 安装的。

新建文件模块:这个方法会帮我们在当前脚本的同目录下新建一个 data 文件夹,里面主要存放我们主机屋登录要用到 cookie 值和当前的 IP。

def createFile(name):
    fp = "data"
    type = ".txt"
    myname = name
    try:
        os.mkdir(fp)
        filename = fp + "/" + myname + type

    except Exception, e:
        # 报错时执行
        if os.path.exists(fp):
            filename =  fp + "/" + myname + type
            print ("Had it!")

        else:
            os.makedirs("." + fp)
            print("Creat in parent directory")
            filename =  fp + "/" + myname + type

    return filename

主机屋登录模块:登录你的主机屋账号密码获取 cookie 并保存到本地文件

def login():
    username = '你的用户名'
    pwd = '你的密码'

    url = "http://www.zhujiwu.com/api/user.php?cmd=Login&username=%s&password=%s" % (username,pwd)
    values = ''
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0',
                'Accept': 'application/json, text/javascript, */*; q=0.01',
                'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
                'Accept-Encoding': 'gzip, deflate',
                'X-Requested-With': 'XMLHttpRequest',
                'Referer': 'http://www.zhujiwu.com/user/login.html',
                'Connection': 'keep-alive'
               }
    try:
        fp = createFile('cookie')
    print '----------'+fp
        c = cookielib.LWPCookieJar(fp)
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(c))

        data = urllib.urlencode(values)
        req = urllib2.Request(url,data,headers)
        response = opener.open(req)
        responsedata = response.read()
        login_data = json.loads(responsedata)
        code = login_data['response']
        if code == '200':
            print 'zhujiwu login sucessful'
            c.save(ignore_expires=True, ignore_discard=True)
            if c:
                return c

    except urllib2.URLError,e:
        print(e)

修改主机屋域名绑定的 IP,当检测到 IP 变化时会调用这个模块,关于你的域名 ID 的获取,我是通过抓包主机屋真实的修改绑定接口获取的,每个域名都不一样。获取 ID 方法

def change(login_cookie,ip):
    my_id = '你的域名id'
    cookie_data = str(login_cookie)
    a = '<LWPCookieJar[<Cookie session_id='
    b = '<_LWPCookieJar.LWPCookieJar[<Cookie session_id='
    d = ' for .zhujiwu.com/>]>'
    cookie_data = cookie_data.replace(a, "")
    cookie_data=  cookie_data.replace(b, "")
    cookie_data=  cookie_data.replace(d, "")

    change_url = "http://www.zhujiwu.com/api/domain.php?cmd=update&content=%s&id=%s&ttl=120"%(ip,my_id)
    change_headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0',
               'Accept': 'application/json, text/javascript, */*; q=0.01',
               'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
               'Accept-Encoding': 'gzip, deflate',
               'X-Requested-With': 'XMLHttpRequest',
               'Referer': 'http://www.zhujiwu.com/control/domain.html',
               'Cookie':'session_id='+cookie_data+'; path=/; domain=zhujiwu.com',
               'Connection': 'keep-alive'
               }
    change_req = urllib2.Request(url=change_url,headers=change_headers)
    change_response = urllib2.urlopen(change_req)
    change_responsedata = change_response.read()
    # print chardet.detect(change_responsedata)
    response = json.loads(change_responsedata.decode('UTF-8-SIG'))
    set_status_code = response['response']
    print set_status_code
    if set_status_code == "200":
        print 'zhujiwu domain set sucessful'

通过访问 ddns.nat123.com 获取我们当前的外网 IP,并通过正则提取写入文件。

def get_local_host():
    url = "http://ddns.nat123.com/"
    try:
        opener = urllib2.build_opener()
        req = urllib2.Request(url)
        response = opener.open(req)
        responsedata = response.read()
        reg = re.compile(r"Address: ([0-9]+.+[0-9]+.+[0-9]+.+[0-9]?)")
        match = reg.search(responsedata)
        Address = match.group(0)
        local_ip = Address.replace('Address: ','')
        return local_ip

    except:
        error_str = 'some wrong ~~~~~~~'
        print error_str
    return error_str

上面把绑定 IP 这个核心功能已经做了,下面这个模块就是只是每分钟获取一次当前的 IP,并和上一分钟的对比,如果发生了变化,就调用上面的设置域名解析接口,把域名绑定到最新的 IP,这个大概会有几分钟的生效时限。

def set_loacl_host():
    print 'the listen is going....'
    while True:
        try:
            file =  open('./data/ip.txt')
            file_data =file.read()
            curr_ip = get_local_host()
            if file_data != curr_ip:
                print 'ip has chang'
                cookie = login()
                change(cookie,curr_ip)
            ip_file_path = createFile('ip')
            ip_file = open(ip_file_path,'w')
            ip_file.write(curr_ip)
            print ('write the curr_ip: %s into ip.txt'%curr_ip)
            ip_file.close()
            file.close()
        except:
            curr_ip = get_local_host()
            file_path = createFile('ip')
            file = open(file_path,'w')
            file.write(curr_ip)
            print ('write the curr_ip: %s into ip.txt'%curr_ip)
            file.close()
        now = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        print (now+"now ip is : %s"%curr_ip)
        time.sleep(60)              

if __name__ == '__main__':
    set_loacl_host()

我的服务器部署在 Linux 上的,涉及到文件的读写,所以在执行这个脚本时要注意权限问题,最好都用 root 用户。
以下是完整代码(其中的账号的 ID 注意要替换成你自己的):

# -*-coding:utf-8-*-
__author__ = "orion-c.win"
import os,time,re,json,time
import urllib
import urllib2
import cookielib


def createFile(name):
    fp = "data"
    type = ".txt"
    myname = name
    try:
        os.mkdir(fp)
        filename = fp + "/" + myname + type

    except Exception, e:
        # 报错时执行
        if os.path.exists(fp):
            filename =  fp + "/" + myname + type
            print ("Had it!")

        else:
            os.makedirs("." + fp)
            print("Creat in parent directory")
            filename =  fp + "/" + myname + type

    return filename

def login():
    username = '你的用户名'
    pwd = '你的密码'

    url = "http://www.zhujiwu.com/api/user.php?cmd=Login&username=%s&password=%s" % (username,pwd)
    values = ''
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0',
                'Accept': 'application/json, text/javascript, */*; q=0.01',
                'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
                'Accept-Encoding': 'gzip, deflate',
                'X-Requested-With': 'XMLHttpRequest',
                'Referer': 'http://www.zhujiwu.com/user/login.html',
                'Connection': 'keep-alive'
               }
    try:
        fp = createFile('cookie')
    print '----------'+fp
        c = cookielib.LWPCookieJar(fp)
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(c))

        data = urllib.urlencode(values)
        req = urllib2.Request(url,data,headers)
        response = opener.open(req)
        responsedata = response.read()
        login_data = json.loads(responsedata)
        code = login_data['response']
        if code == '200':
            print 'zhujiwu login sucessful'
            c.save(ignore_expires=True, ignore_discard=True)
            if c:
                return c

    except urllib2.URLError,e:
        print(e)

def change(login_cookie,ip):
    my_id = '你的域名id'
    cookie_data = str(login_cookie)
    a = '<LWPCookieJar[<Cookie session_id='
    b = '<_LWPCookieJar.LWPCookieJar[<Cookie session_id='
    d = ' for .zhujiwu.com/>]>'
    cookie_data = cookie_data.replace(a, "")
    cookie_data=  cookie_data.replace(b, "")
    cookie_data=  cookie_data.replace(d, "")

    change_url = "http://www.zhujiwu.com/api/domain.php?cmd=update&content=%s&id=%s&ttl=120"%(ip,my_id)
    change_headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0',
               'Accept': 'application/json, text/javascript, */*; q=0.01',
               'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
               'Accept-Encoding': 'gzip, deflate',
               'X-Requested-With': 'XMLHttpRequest',
               'Referer': 'http://www.zhujiwu.com/control/domain.html',
               'Cookie':'session_id='+cookie_data+'; path=/; domain=zhujiwu.com',
               'Connection': 'keep-alive'
               }
    change_req = urllib2.Request(url=change_url,headers=change_headers)
    change_response = urllib2.urlopen(change_req)
    change_responsedata = change_response.read()
    # print chardet.detect(change_responsedata)
    response = json.loads(change_responsedata.decode('UTF-8-SIG'))
    set_status_code = response['response']
    print set_status_code
    if set_status_code == "200":
        print 'zhujiwu domain set sucessful'

def get_local_host():
    url = "http://ddns.nat123.com/"
    try:
        opener = urllib2.build_opener()
        req = urllib2.Request(url)
        response = opener.open(req)
        responsedata = response.read()
        reg = re.compile(r"Address: ([0-9]+.+[0-9]+.+[0-9]+.+[0-9]?)")
        match = reg.search(responsedata)
        Address = match.group(0)
        local_ip = Address.replace('Address: ','')
        return local_ip

    except:
        error_str = 'some wrong ~~~~~~~'
        print error_str
    return error_str

def set_loacl_host():
    print 'the listen is going....'
    while True:
        try:
            file =  open('./data/ip.txt')
            file_data =file.read()
            curr_ip = get_local_host()
            if file_data != curr_ip:
                print 'ip has chang'
                cookie = login()
                change(cookie,curr_ip)
            ip_file_path = createFile('ip')
            ip_file = open(ip_file_path,'w')
            ip_file.write(curr_ip)
            print ('write the curr_ip: %s into ip.txt'%curr_ip)
            ip_file.close()
            file.close()
        except:
            curr_ip = get_local_host()
            file_path = createFile('ip')
            file = open(file_path,'w')
            file.write(curr_ip)
            print ('write the curr_ip: %s into ip.txt'%curr_ip)
            file.close()
        now = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        print (now+"now ip is : %s"%curr_ip)
        time.sleep(60)


if __name__ == '__main__':
    set_loacl_host()

保持脚本执行就可以实现动态 IP 的域名绑定了。


↙↙↙阅读原文可查看相关链接,并与作者交流