2017-04-06 180 views
3

使用telnetlib我從我的路由器中獲取路由信息,並且想要使用模式提取WAN IP地址。 telnet會話的輸出位於一個變量中,行之間用\ n分隔。Python從telnetlib輸出獲取IP地址

來自telnet會話的東西。

l= tn.read_all() 
>>> l 
'\r\nip -f inet addr\r\nexit\r\[email protected]:/tmp/home/root# ip -f inet addr\r\n1: lo: <LOOPBACK,MULTICAST,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN \r\n inet 127.0.0.1/8 brd 127.255.255.255 scope host lo\r\n2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\r\n inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0\r\n7: br0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN \r\n inet 192.168.11.1/24 brd 192.168.11.255 scope global br0\r\n8: tun21: <POINTOPOINT,MULTICAST,NOARP,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 100\r\n inet 10.8.0.1 peer 10.8.0.2/32 scope global tun21\r\[email protected]:/tmp/home/root# exit\r\n' 
>>> 

現在我的代碼。

l= tn.read_all() 
for line in l.split('\n'): 
    match= re.findall(r'([0-9]+(?:\.[0-9]+){3}).*scope global eth0', line) 
    if match is not None: 
     print('Found ' + line) 

我本來料想到一行符合打印。

Found  inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0 

但我得到無處不在。

Found 
Found ip -f inet addr 
Found exit 
Found [email protected]:/tmp/home/root# ip -f inet addr 
Found 1: lo: <LOOPBACK,MULTICAST,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
Found  inet 127.0.0.1/8 brd 127.255.255.255 scope host lo 
Found 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 
Found  inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0 
Found 7: br0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
Found  inet 192.168.11.1/24 brd 192.168.11.255 scope global br0 
Found 8: tun21: <POINTOPOINT,MULTICAST,NOARP,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 100 
Found  inet 10.8.0.1 peer 10.8.0.2/32 scope global tun21 
Found [email protected]:/tmp/home/root# exit 
Found 

我找不出爲什麼我的代碼失敗。如果專家有一個更好的方法(解釋),那會很好。

編輯:

揚的回答肯定是更Python,但我缺乏蟒蛇的知識讓我更喜歡VKS這是容易理解我。我給了兩個'^',並將vks標記爲首選(在「我偏好的意義上」)。

我最終在'split'cmd和下面的代碼中使用'\ r \ n'。

def get_asus_wan_ip(): 
    "Gets WAN IP from ASUS router" 

    import telnetlib 
    import re 

    ASUS_IP= '192.168.1.1' 
    ASUS_USER= 'xxxxxxxx' 
    ASUS_PASS= 'yyyyyyyy' 
    tn = telnetlib.Telnet(ASUS_IP) 

    tn.read_until("login: ") 
    tn.write(ASUS_USER + "\n") 
    tn.read_until("Password: ") 
    tn.write(ASUS_PASS + "\n") 
    tn.write("ifconfig eth0\n") 
    tn.write("exit\n") 
    l= tn.read_all() 
    for line in l.split('\r\n'): 
     match= re.findall(r'^\s+inet addr:([0-9]+(?:\.[0-9]+){3}).*', line) 
     if match: 
      break 

    wan_ip= match[0] 
    return wan_ip 
+2

''re.findall()''返回一個*列表*的匹配。該列表可以是空的;它不可能是「None」。對於單個匹配,如果匹配必須位於字符串的起始位置,則需要''re.search()''(或re.match()'')。 – jasonharper

+0

你的[**正則表達式工作正常**](https://regex101.com/r/rfgo3G/1)(稍微調整),'if'構造是問題。 – Jan

+0

[從html字符串(python)提取IP地址的可能重複](http://stackoverflow.com/questions/2890896/extract-ip-address-from-an-html-string-python) – philshem

回答

3
import re 
x="""'\r\nip -f inet addr\r\nexit\r\[email protected]:/tmp/home/root# ip -f inet addr\r\n1: lo: <LOOPBACK,MULTICAST,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN \r\n inet 127.0.0.1/8 brd 127.255.255.255 scope host lo\r\n2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\r\n inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0\r\n7: br0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN \r\n inet 192.168.11.1/24 brd 192.168.11.255 scope global br0\r\n8: tun21: <POINTOPOINT,MULTICAST,NOARP,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 100\r\n inet 10.8.0.1 peer 10.8.0.2/32 scope global tun21\r\[email protected]:/tmp/home/root# exit\r\n'""" 
for line in x.split('\n'): 
    match= re.findall(r'(?:[0-9]+(?:\.[0-9]+){3}).*scope global eth0', line) 
    if match: 
     print('Found ' + line) 

輸出:Found inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0

個問題與您的代碼:

1)re.findall回報list,所以它不可能是None它可以empty.So使用,在if條件。

2)re.findall只返回組,如果有一些。如果你想整行,使第一組不捕獲。

2

您可以大大與列表理解收縮代碼:

import re 

string = """ 
1: lo: <LOOPBACK,MULTICAST,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo 
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 
    inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0 
7: br0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
    inet 192.168.11.1/24 brd 192.168.11.255 scope global br0 
8: tun21: <POINTOPOINT,MULTICAST,NOARP,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 100 
    inet 10.8.0.1 peer 10.8.0.2/32 scope global tun21 
""" 

rx = re.compile(r'\b(\d+(?:\.\d+){3})\b.*scope global eth0') 
matches = [line 
      for line in string.split("\n") 
      for match in [rx.search(line)] 
      if match] 
print(matches) 
# [' inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0'] 

或者如果你喜歡filter()lambda()

matches = list(filter(lambda x: rx.search(x), string.split("\n"))) 
print(matches)