LoginSignup
8
8

More than 5 years have passed since last update.

Python, Selenium, PhantomJSを使ってルータを再起動する

Posted at

概要

Python, Selenium, PhantomJSを使ってルータを再起動、並びに、ルータからWAN側IPアドレスを取得します。

経緯

自宅がまだ固定IPアドレスではないため外部から自宅へ接続しようとすると、その都度自宅に設置しているルータのWAN側IPアドレスを調べる必要があります。これまでは外部サーバを利用して自宅LANからWAN側IPアドレスを取得する方法を採用していました。このとき、ルータの問題なのかプロバイダの問題なのかは不明なのですが、時々外部との通信ができなくなる場合がありました。これはルータを再起動することで回復することは分かっていました。ただ、外出中に自宅との通信ができなくなった場合、外部から再起動することができず、自宅に帰るまで復旧不可に陥っていました。この状況では自宅から数日間離れる場合に大きな問題になっていました。

この問題を解消するために、可能な限り今ある環境で安くできればと今回ご紹介する方法を採用しました。すなわち、Selenium, PhantomJSを使用して通信障害発生時にルータを再起動させるようにしました。もっと良い方法があるかと思われますが、この方法でルータを再起動し、さらにルータから直接WAN側IPアドレスを取得することができるようになり、LAN内だけで完結できるようになりました。
本内容が他の方々のお役に立てることができればと投稿させていただきました。

準備

このスクリプトが対象としているルータはNTTからお借りしているONUとルーターが一体型の三菱電機社製 PR-500MIです。他のルータをご使用の場合はそれぞれの環境に合わせてご変更をお願いします。スクリプトを使用するために必要なものは次の通りです。

  1. Python

  2. Selenium(pip install selenium でインストールします。)

  3. PhantomJS(npm install -g phantomjs でインストールするかあるいはhttp://phantomjs.org/download.htmlからダウンロード、解凍してパスを通します。)

  4. beautifulsoup4(pip install beautifulsoup4 でインストールします。)

ルータへアクセスするためのURLは次の通りです。PR-500MIはBasic認証のため、ログインして情報を取得するために下記のように入力します。

http://ユーザ名:パスワード@ルータのIPアドレス

ユーザ名、パスワードはルータへログインする際のアカウントです。ルータのIPアドレスは設定した際のものです。いつもログインする際のアドレスでも問題ありません。そのあとに続けて取得したい情報があるURLを付け加えます。

スクリプト

from bs4 import BeautifulSoup
from selenium import webdriver


class pr500mi(object):
    """This is for PR-500MI."""

    def __init__(self):
        self.baseurl = 'http://ユーザ名:パスワード@ルータのIPアドレス'
        self.driver = webdriver.PhantomJS()

    def getip(self):
        getipurl = self.baseurl + '/ntt/information/fifth/current/'
        self.driver.get(getipurl)
        html = self.driver.page_source.encode('utf-8')
        soup = BeautifulSoup(html, 'lxml')
        ip = soup.findAll(class_='section')[6].findAll('td')
        return (ip[1].get_text(), ip[21].get_text()) # ipv4, ipv6

    def reboot(self):
        rebooturl = self.baseurl + '/ntt/userMaintenance/reboot/'
        self.driver.get(rebooturl)
        self.driver.find_element_by_id('REBOOT').click()

getip()でWAN側のipv4, ipv6のipアドレスの取得、reboot()でルータを再起動させます。URLの'/ntt/information/fifth/current/', '/ntt/userMaintenance/reboot/'、並びにスクリプト最後の2行(ip, ipv4, ipv6)はファームウェアのアップデートで変化する可能性がありますので、ファームウェアがアップデートして動作しなくなった場合にはご確認下さい。

ルータを再起動させる際は、再起動後にWAN側IPアドレスを取得する必要がありますのでsleepを使って再起動完了まで待つように設定した後(2分程度)にIPアドレスの取得を行ってください。

私はメールで上記スクリプトを実行しています。メール受信をトリガーとしてIPアドレスの通知やルータの再起動を行っています。また、今の段階ではWAN側IP取得と再起動が主な目的でしたが、上記のスクリプトへ付け加えることで切断や再接続、NAT設定、ログ参照なども行うことが可能になります。今後はルータの電源をオン、オフするための設備追加を行うことで、2段階で再起動ができるようにしたいと思っています。

需要があるかどうかはわかりませんが、機種ごとにコマンドラインから制御するためのライブラリを作成してもよいかもしれませんね。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8