使用selenium来对DDNS定时更新

Zss 发表于:

使用的是no-ip,免费版的,但是每三十天需要确认一个次,由于搭建了esxi虚拟机,所在esxi中创建的win7,正好可以来使用ui操作对ddns进行更新,发现把旧的dns删除点,再次添加一个和原来一样的dns解析,时间会重置为30天,所以在win7的虚拟机上挂一个脚本,每天定时对网站上的ddns删除,添加操作,这样就不需要来确认邮件了

但是发现国外的网站进入很慢,加上虚拟机的性能不怎么样,可能自动操作是会容易出错,所以做了一些重操作的机制

每次更新的前会去路由器获取一下wan的ip,保证了每次更新都是最新的动态公网ip

会产生日志,通过日志可以看到最终失败还是成功了

2019 - 03 - 15 - 15 - 01 - 05 --> 时间未到14点,不进行DDNS更新,等待10分钟重新检测
2019 - 03 - 15 - 15 - 01 - 23 --> 当前时间已到设置时间,开始更新DDNS
2019 - 03 - 15 - 15 - 01 - 26 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 01 - 48 --> 正在登陆路由器获取WAN_IP
2019 - 03 - 15 - 15 - 02 - 21 --> 获取IP失败! error
info:Message: no
such
element: Unable
to
locate
element: {"method": "xpath", "selector": "//*[@id="upstream_status_table"]/div[1]/div[2]/span/span[2]"}
(Session info: chrome=71.0.3578.80)
(Driver info: chromedriver=71.0.3578.80 (2ac50e7249fbd55e6f517a28131605c9fb9fe897), platform = Windows
NT
6.1
.7600
x86)

2019 - 03 - 15 - 15 - 02 - 21 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 03 - 28 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 03 - 28 --> 正在打开https: // www.noip.com / login登录页面
2019 - 03 - 15 - 15 - 03 - 28 --> 开始登录账号:xxxx@ qq.com
2019 - 03 - 15 - 15 - 04 - 32 --> xxxx @ qq.com账号登录失败,可能被限制或者网速问题, 等待五分钟后自动重新尝试
2019 - 03 - 15 - 15 - 17 - 58 --> 当前时间已到设置时间,开始更新DDNS
2019 - 03 - 15 - 15 - 18 - 00 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 18 - 03 --> 正在登陆路由器获取WAN_IP
2019 - 03 - 15 - 15 - 18 - 10 --> 获取到WAN侧IP为:175.10.34].161
2019 - 03 - 15 - 15 - 18 - 10 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 18 - 25 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 18 - 25 --> 正在打开https: // www.noip.com / login登录页面
2019 - 03 - 15 - 15 - 18 - 56 --> 当前时间已到设置时间,开始更新DDNS
2019 - 03 - 15 - 15 - 18 - 58 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 19 - 00 --> 正在登陆路由器获取WAN_IP
2019 - 03 - 15 - 15 - 19 - 0
8 --> 获取到WAN侧IP为:175.10.34.161
2019 - 03 - 15 - 15 - 19 - 0
8 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 19 - 25 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 19 - 25 --> 正在打开https: // www.noip.com / login登录页面
2019 - 03 - 15 - 15 - 19 - 31 --> 当前时间已到设置时间,开始更新DDNS
2019 - 03 - 15 - 15 - 19 - 34 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 19 - 35 --> 正在登陆路由器获取WAN_IP
2019 - 03 - 15 - 15 - 19 - 40 --> 获取到WAN侧IP为:175.10.34.161
2019 - 03 - 15 - 15 - 19 - 42 --> 退出路由器登录
2019 - 03 - 15 - 15 - 19 - 44 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 20 - 17 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 20 - 17 --> 正在打开https: // www.noip.com / login登录页面
2019 - 03 - 15 - 15 - 20 - 18 --> 开始登录账号:465193527 @ qq.com
2019 - 03 - 15 - 15 - 20 - 50 --> zss1994427账号成功登录!!!
2019 - 03 - 15 - 15 - 20 - 52 --> 开始进入详细页面
2019 - 03 - 15 - 15 - 20 - 53 --> 发现删除按钮,此时存在DDNS,删除旧DDNS解析,添加新的DDNS
2019 - 03 - 15 - 15 - 21 - 35 --> - -- -- -- -- -- -- -- -- -- -
2019 - 03 - 15 - 15 - 21 - 35 --> 正在打开https: // www.noip.com / login登录页面
2019 - 03 - 15 - 15 - 21 - 35 --> 开始登录账号:465193527 @ qq.com
2019 - 03 - 15 - 15 - 21 - 42 --> zss1994427账号成功登录!!!
2019 - 03 - 15 - 15 - 21 - 44 --> 开始进入详细页面
2019 - 03 - 15 - 15 - 21 - 45 --> 发现删除按钮,此时存在DDNS,删除旧DDNS解析,添加新的DDNS
2019 - 03 - 15 - 15 - 21 - 45 --> 点击删除, 开始删除旧DDNS
2019 - 03 - 15 - 15 - 21 - 46 --> 点击确认, 确认删除旧DDNS
2019 - 03 - 15 - 15 - 22 - 14 --> 开始进入个人主机名页面
2019 - 03 - 15 - 15 - 22 - 18 --> 点击添加新的主机名
2019 - 03 - 15 - 15 - 22 - 18 --> 清除掉DDNS_NAME冗余信息
2019 - 03 - 15 - 15 - 22 - 19 --> 添加新的DDNS_NAME:zww
2019 - 03 - 15 - 15 - 22 - 19 --> 清除掉DDNS_IP冗余信息
2019 - 03 - 15 - 15 - 22 - 20 --> 添加新的DDNS_IP:175.10.34.161
2019 - 03 - 15 - 15 - 22 - 23 --> 添加成功!!!
2019 - 03 - 15 - 15 - 22 - 24 --> 开始退出登录
2019 - 03 - 15 - 15 - 22 - 30 --> 成功登出!!!
2019 - 03 - 15 - 15 - 22 - 30 --> 关闭浏览器
2019 - 03 - 15 - 15 - 22 - 30 --> - -- -- -- -- -- -- -- -- -- -

2019 - 03 - 15 - 15 - 22 - 33 --> 等待24小时后,在15点来重新添加新的DDNS, 来保证激活天数
2019 - 03 - 15 - 15 - 25 - 51 --> 时间未到03点,不进行DDNS更新,等待10分钟重新检测
# coding:gbk
from selenium import webdriver
import time,re,sys,os
from selenium.webdriver.chrome.options import Options
reload(sys)
sys.setdefaultencoding("gbk")
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
if not os.path.exists('no_ip_log'):
    os.mkdir('no_ip_log')


def is_exist_element(elem):
    if elem[:2] == '//':
        s = web.find_elements_by_xpath(elem)
    else:
        s = web.find_elements_by_css_selector(elem)

    if len(s) == 0:
        return False
    if len(s) == 1:
        return True
    else:
        return False


def print_log(text):
    log_name = os.getcwd() + '//no_ip_log//' + start_time + '_noip_log.txt'
    try:
        info = '%s --> %s \n' % (time.strftime('%Y-%m-%d-%H-%M-%S'), text)
        print info
        with open(log_name, 'a') as f:
            f.write(info)
    except Exception as e:
        error = '%s --> %s \n' % (time.strftime('%Y-%m-%d-%H-%M-%S'), e)
        print error
        with open(log_name, 'a') as f:
            f.write(error)


def main(web):
    web.implicitly_wait(30)
    web.get('https://www.noip.com/login')
    print_log('- -' * 10)
    print_log('正在打开https://www.noip.com/login登录页面')

    # 登录
    web.find_element_by_xpath('//*[@id="clogs"]/input[2]').send_keys(noip_user)
    print_log('开始登录账号:%s' % noip_user)
    web.find_element_by_xpath('//*[@id="clogs"]/input[3]').send_keys(noip_passwd)
    web.find_element_by_xpath('//*[@id="clogs"]/button').click()
    time.sleep(1)

    # 判断是否登录成功
    if is_exist_element('//*[@id="content-wrapper"]/div[1]/div[1]/div/div/div/h1') == False:
        print_log('%s账号登录失败,可能被限制或者网速问题,等待五分钟后自动重新尝试' % noip_user)
        web.quit()
        time.sleep(300)
        return False
    else:
        print_log('%s账号成功登录!!!' % noip_passwd)

        # 进入详细页面
        time.sleep(1)
        web.find_element_by_xpath(
            '//*[@id="content-wrapper"]/div[1]/div[2]/div[1]/div[1]/div[1]/div/div/div/div/div').click()
        print_log('开始进入详细页面')
        time.sleep(1)
        # 判断是否存在删除按钮,有则删除添加,没有则直接添加
        if is_exist_element('#host-panel > table > tbody > tr:nth-child(1) > td.text-right-md > div > i') == True:
            print_log('发现删除按钮,此时存在DDNS,删除旧DDNS解析,添加新的DDNS')

            # 删除
            web.find_element_by_css_selector(
                '#host-panel > table > tbody > tr:nth-child(1) > td.text-right-md > div > i').click()
            print_log('点击删除,开始删除旧DDNS')
            time.sleep(1)
            web.find_element_by_css_selector(
                '#content-wrapper > div:nth-child(1) > div.row > div.col-md-9 > div > div:nth-child(1) > div.modal.fade.modal-update.in > div > div > div.modal-footer > button.btn.btn-flat.btn-danger.btn-round-corners.ml-sm-30.pr-sm').click()
            print_log('点击确认,确认删除旧DDNS')
            time.sleep(1)

            # 添加
            web.find_element_by_css_selector(
                '#main-menu-inner > ul > li.mm-dropdown.open.mm-dropdown-root > ul > li:nth-child(2) > a > span').click()
            print_log('开始进入个人主机名页面')
            time.sleep(1)
            web.find_element_by_css_selector('#host-panel > div.panel-footer > a > span').click()
            print_log('点击添加新的主机名')
            time.sleep(0.5)
            web.find_element_by_css_selector('#hostname').clear()
            print_log('清除掉DDNS_NAME冗余信息')
            time.sleep(0.5)
            web.find_element_by_css_selector('#hostname').send_keys(noip_ddns_name)
            print_log('添加新的DDNS_NAME:%s' % noip_ddns_name)
            time.sleep(0.5)
            web.find_element_by_css_selector('#ip').clear()
            print_log('清除掉DDNS_IP冗余信息')
            time.sleep(0.5)
            web.find_element_by_css_selector('#ip').send_keys(noip_ddns_ip)
            print_log('添加新的DDNS_IP:%s' % noip_ddns_ip)
            time.sleep(0.5)
            web.find_element_by_css_selector('#tab-content > div > div > form > div > div.form-footer.text-right > input.btn.btn-success').click()
            print_log('添加成功!!!')
            web.find_element_by_css_selector('#user-email-container > a > div').click()
            time.sleep(0.5)
            print_log('开始退出登录')
            web.find_element_by_css_selector('#user-email-container > ul > li.hidden-xs > a').click()
            time.sleep(0.5)
            print_log('成功登出!!!')
            print_log('关闭浏览器')
            print_log('- -' * 10 + '\n')
            time.sleep(0.5)
            web.quit()
            return True

        else:
            print_log('检测到暂无DDNS列表,添加新的DDNS')
            time.sleep(1)
            web.find_element_by_css_selector(
                '#main-menu-inner > ul > li.mm-dropdown.open.mm-dropdown-root > ul > li:nth-child(2) > a > span').click()
            print_log('开始进入个人主机名页面')
            time.sleep(1)
            web.find_element_by_css_selector('#host-panel > div.panel-footer > a > span').click()
            print_log('点击添加新的主机名')
            time.sleep(0.5)
            web.find_element_by_css_selector('#hostname').clear()
            print_log('清除掉DDNS_NAME冗余信息')
            time.sleep(0.5)
            web.find_element_by_css_selector('#hostname').send_keys(noip_ddns_name)
            print_log('添加新的DDNS_NAME:%s' % noip_ddns_name)
            time.sleep(0.5)
            web.find_element_by_css_selector('#ip').clear()
            print_log('清除掉DDNS_IP冗余信息')
            time.sleep(0.5)
            web.find_element_by_css_selector('#ip').send_keys(noip_ddns_ip)
            print_log('添加新的DDNS_IP:%s' % noip_ddns_ip)
            time.sleep(0.5)
            web.find_element_by_css_selector('#tab-content > div > div > form > div > div.form-footer.text-right > input.btn.btn-success').click()
            print_log('添加成功!!!')
            web.find_element_by_css_selector('#user-email-container > a > div').click()
            time.sleep(0.5)
            print_log('开始退出登录')
            web.find_element_by_css_selector('#user-email-container > ul > li.hidden-xs > a').click()
            time.sleep(0.5)
            print_log('成功登出!!!')
            print_log('关闭浏览器')
            print_log('- -' * 10 + '\n')
            time.sleep(0.5)
            web.quit()
            return True


def get_wan_ip(ap_web):
    try:
        ap_web.implicitly_wait(30)
        print_log('- -' * 10)
        ap_web.get(ap_ip)
        print_log('正在登陆路由器获取WAN_IP')
        ap_web.find_element_by_css_selector('#maincontent > div > form > div.cbi-map > div.cbi-section > div > div.cbi-value.cbi-value-last > div > input').send_keys('xxxxx')
        time.sleep(1)
        ap_web.find_element_by_css_selector('#maincontent > div > form > div.cbi-page-actions > input.cbi-button.cbi-button-apply').click()
        time.sleep(1)
        info = ap_web.find_element_by_xpath('//*[@id="upstream_status_table"]/div[1]/div[2]/span/span[2]').text
        ip = re.findall('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}',info)[0]
        print_log('获取到WAN侧IP为:%s' % ip)
        ap_web.find_element_by_css_selector('body > div.main > div.main-left > ul > li:nth-child(7) > a').click()
        print_log('退出路由器登录')
        ap_web.quit()
        print_log('- -' * 10)
        return ip
    except Exception as e:
        print_log('获取IP失败! error info:%s'%e)
        print_log('- -' * 10)
        ap_web.quit()

def start_run():
    the_time = time.strftime('%H')
    if the_time == loop_Hour:
        print_log('当前时间已到设置时间,开始更新DDNS')
        return True
    else:
        print_log('时间未到%s点,不进行DDNS更新,等待10分钟重新检测'% loop_Hour)
        return False


if __name__ == '__main__':
    #LEDE路由器IP设置
    ap_ip = 'http://192.168.98.1/cgi-bin/luci/'
    #noip账号
    noip_user = 'xxx'
    #noip密码
    noip_passwd = 'xxx'
    #noip 域名前缀 更新默认使用.ddns.net后缀
    noip_ddns_name = 'xxxx'
    #每次更新后延时(秒)
    loop_time = 86400
    #开始更新的时间点(小时00-23)
    loop_Hour = '15'
    #开启无头模式
    headers_enable = 0

    start_time = time.strftime('%Y-%m-%d')
    while 1:
        while start_run():
            try:
                if headers_enable == 1:
                    ap_web = webdriver.PhantomJS()
                else:
                    ap_web = webdriver.Chrome()
                noip_ddns_ip = get_wan_ip(ap_web)

                if headers_enable == 1:
                    web = webdriver.PhantomJS()
                else:
                    web = webdriver.Chrome()

                while 1:
                    try:
                        if main(web) == False:
                            continue
                        else:break
                    except:pass

                print_log('等待24小时后,在%s点来重新添加新的DDNS,来保证激活天数'%loop_Hour)
                time.sleep(loop_time)
            except Exception as e:
                print_log(e)
                time.sleep(10)
        time.sleep(600)