Python获取ip地址
来源:互联网 发布:linux 没有tmp文件夹 编辑:程序博客网 时间:2024/06/05 15:31
1. 获取ip/MAC地址等
获取本地ip地址首先想到的命令是ifconfig,然后从结果中提取出ip地址,Python代码如下:
def get_ip(): cmd = "/sbin/ifconfig | grep 'inet addr' | grep -v 127.0.0.1 | awk '{print $2}' | awk -F ':' '{print $2}'" pip = subprocess.Popen(cmd, shell = True, stdout = subprocess.PIPE) ip = pip.stdout.read() return ip可能大家会觉得这样太山寨或者结果不太可信。而事实上,有一个包可以实现提取ip地址,它就是netifaces。netifaces官网地址是:https://pypi.python.org/pypi/netifaces/,里面有详细的介绍和示例。下面给出使用netifaces取得ip地址的代码:
import netifacesdef get_current_ip(): ''' Using netifaces to fetch the ip address of the current machine. ''' ips = [] exclude_iface = ['lo'] interfaces = netifaces.interfaces() for iface in interfaces: if iface not in exclude_iface: if netifaces.AF_INET in netifaces.ifaddresses(iface): addrs = netifaces.ifaddresses(iface)[netifaces.AF_INET] # mac addr: netifaces.AF_LINK for addr in addrs: ips.append(info['addr']) return ipsips = get_current_ip()print ips
netifaces.ifaddresses(iface)返回一个字典,其中key为:18,2和30,分别代表协议:AF_LINK、AF_INET(IPV4)和AF_INET6 (IPv6)。上面代码中的addrs为一个列表(因为一台主机可以由多个ip地址),列表中的每个元素是一个字典,包含了广播地址(broadcast)、子网掩码(netmask)和IP地址(addr)。事实上netifaces除了可以查询上述信息,还可以查询物理地址(MAC地址或网卡地址)、网关(使用netifaces.gateways()),网关结果类似于:{'default': {2: ('192.168.1.1', 'eth0')}, 2: [('192.168.1.1', 'eth0', True)]},其中的key 2表示协议AF_INET(IPV4)。
2. 处理ip
取得ip地址后,若要对ip地址进行处理,则要用到subnets包,subnet官网教程,以下是摘取部分:
基本操作
In [1]: from netaddr import *In [2]: import pprintIn [3]: ip = IPAddress("192.168.2.151")In [4]: ip.versionOut[4]: 4In [5]: repr(ip)Out[5]: "IPAddress('192.168.2.151')"In [6]: ipOut[6]: IPAddress('192.168.2.151')In [7]: str(ip)Out[7]: '192.168.2.151'In [8]: '%s' % ipOut[8]: '192.168.2.151'In [9]: ip.format()Out[9]: '192.168.2.151'可以查看ip地址的其他进制格式:
In [11]: int(ip)Out[11]: 3232236183LIn [12]: hex(ip)Out[12]: '0xc0a80297'In [13]: ip.binOut[13]: '0b11000000101010000000001010010111'In [14]: ip.bits()Out[14]: '11000000.10101000.00000010.10010111'In [15]: ip.words == (192,168,2,151)Out[15]: True
网络/子网
IPNetwork: IPNetwork模块用于处理子网、子网掩码、CIDR表示的VLAN或网络In [18]: ip = IPNetwork('192.168.2.151')In [19]: ip.ipOut[19]: IPAddress('192.168.2.151')In [20]: ip.network, ip.broadcastOut[20]: (IPAddress('192.168.2.151'), IPAddress('192.168.2.151'))In [21]: ip.sizeOut[21]: 1上述情况下,网络和广播地址是一样的,如果采用CIDR地址块,则:
In [22]: ip = IPNetwork('192.168.2.151/24')In [23]: ip.ipOut[23]: IPAddress('192.168.2.151')In [24]: ip.network, ip.broadcastOut[24]: (IPAddress('192.168.2.0'), IPAddress('192.168.2.255'))In [25]: ip.netmask, ip.hostmaskOut[25]: (IPAddress('255.255.255.0'), IPAddress('0.0.0.255'))<pre name="code" class="python">
In [26]: ip.sizeOut[26]: 256上述结果得到了相应的ip地址,子网地址,广播地址,IP掩码和主机号掩码以及该网络容纳ip的数量。对应一个已有的IPNetwork,同样可以更改ip地址和CIDR的前缀:
In [27]: ip = IPNetwork('0.0.0.0/0')In [28]: ipOut[28]: IPNetwork('0.0.0.0/0')In [29]: ip.value = 3221225985In [30]: ipOut[30]: IPNetwork('192.0.2.1/0')In [31]: ip.prefixlenOut[31]: 0In [32]: ip.prefixlen=23In [33]: ipOut[33]: IPNetwork('192.0.2.1/23')
In [35]: ip.cidrOut[35]: IPNetwork('192.0.2.0/23')
In [36]: ip.ip.bits()Out[36]: '11000000.00000000.00000010.00000001'In [37]: ip.network.bits()Out[37]: '11000000.00000000.00000010.00000000'In [38]: ip.netmask.bits()Out[38]: '11111111.11111111.11111110.00000000'In [39]: ip.broadcast.bits()Out[39]: '11000000.00000000.00000011.11111111'
IPv6
netaddr还提供了对IPv6的支持,例如:In [40]: ip = IPAddress(0,6)In [41]: ipOut[41]: IPAddress('::')In [43]: ip = IPNetwork('fe80::dead:beef/64')In [44]: str(ip), ip.prefixlen, ip.versionOut[44]: ('fe80::dead:beef/64', 64, 6)In [45]: int(ip.ip)Out[45]: 338288524927261089654018896845083623151LIn [46]: hex(ip.ip)Out[46]: '0xfe8000000000000000000000deadbeef'
In [47]: ip.ip.bits()Out[47]: '1111111010000000:0000000000000000:0000000000000000:0000000000000000:0000000000000000:0000000000000000:1101111010101101:1011111011101111'In [48]: ip.network, ip.broadcast, ip.netmask, ip.hostmaskOut[48]: (IPAddress('fe80::'), IPAddress('fe80::ffff:ffff:ffff:ffff'), IPAddress('ffff:ffff:ffff:ffff::'), IPAddress('::ffff:ffff:ffff:ffff'))
IPv6转IPv4
In [50]: IPNetwork('::ffff:192.0.2.1/119').ipv6()Out[50]: IPNetwork('::ffff:192.0.2.1/119')In [52]: IPNetwork('::ffff:192.0.2.1/119').ipv6(ipv4_compatible=True)Out[52]: IPNetwork('::192.0.2.1/119')In [53]: IPNetwork('::ffff:192.0.2.1/119').ipv4()Out[53]: IPNetwork('192.0.2.1/23')In [54]: IPNetwork('::192.0.2.1/119').ipv4()Out[54]: IPNetwork('192.0.2.1/23')
IP 列表
使用IPNetwork模块来进行网络操作,事实上,返回的是一个IPNetwork类型,要得到网段内的ip地址列表,需要调用list方法:In [2]: ip = IPNetwork('192.168.2.151/29')In [3]: type(ip)Out[3]: netaddr.ip.IPNetworkIn [4]: type(ip[0:-1])Out[4]: generatorIn [5]: ip_list = list(ip)In [6]: ip_listOut[6]: [IPAddress('192.168.2.144'), IPAddress('192.168.2.145'), IPAddress('192.168.2.146'), IPAddress('192.168.2.147'), IPAddress('192.168.2.148'), IPAddress('192.168.2.149'), IPAddress('192.168.2.150'), IPAddress('192.168.2.151')]In [7]: ip[-1]Out[7]: IPAddress('192.168.2.151')In [8]: ip[0]Out[8]: IPAddress('192.168.2.144')In [9]: ip[0:4]Out[9]: <generator object iter_iprange at 0xb61ec414>In [10]: list(ip[0::2])Out[10]: [IPAddress('192.168.2.144'), IPAddress('192.168.2.146'), IPAddress('192.168.2.148'), IPAddress('192.168.2.150')]In [11]: list(ip[-1::-1])Out[11]: [IPAddress('192.168.2.151'), IPAddress('192.168.2.150'), IPAddress('192.168.2.149'), IPAddress('192.168.2.148'), IPAddress('192.168.2.147'), IPAddress('192.168.2.146'), IPAddress('192.168.2.145'), IPAddress('192.168.2.144')]可见,ip[XXX]的形式其实就是一个生成器,生成器的目的是保证在处理拥有大量ip的网络时降低对资源的占用。
In [15]: for ip in IPNetwork('192.0.2.0/23'): ....: print ipout [15]:192.0.2.0192.0.2.1192.0.2.2192.0.2.3...192.0.3.252192.0.3.253192.0.3.254192.0.3.255上述结果中:192.0.2.0和192.0.3.255并不是有效的主机地址,而是网络地址和广播地址。为了得到有效的主机地址,则需要使用iter_hosts()
[16]:for ip in IPNetwork('192.0.2.0/23').iter_hosts():... print '%s' % ipout [16]: 192.0.2.1192.0.2.2192.0.2.3192.0.2.4...192.0.3.251192.0.3.252192.0.3.253192.0.3.254
排序
对IP和网络进行排序的方法是使用sorted函数:
In [16]: ip_list = list(IPNetwork('192.0.2.128/28'))In [17]: sorted(ip_list)Out[17]: [IPAddress('192.0.2.128'), IPAddress('192.0.2.129'), IPAddress('192.0.2.130'), IPAddress('192.0.2.131'), IPAddress('192.0.2.132'), IPAddress('192.0.2.133'), IPAddress('192.0.2.134'), IPAddress('192.0.2.135'), IPAddress('192.0.2.136'), IPAddress('192.0.2.137'), IPAddress('192.0.2.138'), IPAddress('192.0.2.139'), IPAddress('192.0.2.140'), IPAddress('192.0.2.141'), IPAddress('192.0.2.142'), IPAddress('192.0.2.143')]
为了方便起见,也可以对网络进行排序,并且IPv4和IPv6网络可以混排。例如:
In [18]: ip_list = [ ....: IPAddress('192.0.2.130'), ....: IPAddress('10.0.0.1'), ....: IPNetwork('192.0.2.128/28'), ....: IPNetwork('192.0.3.0/24'), ....: IPNetwork('192.0.2.0/24'), ....: IPNetwork('fe80::/64'), ....: IPAddress('::'), ....: IPNetwork('172.24/12')]In [19]: import randomIn [20]: random.shuffle(ip_list)In [21]: ip_list.sort()In [23]: import pprintIn [24]: pprint.pprint(ip_list)[IPAddress('10.0.0.1'), IPNetwork('172.24.0.0/12'), IPNetwork('192.0.2.0/24'), IPNetwork('192.0.2.128/28'), IPAddress('192.0.2.130'), IPNetwork('192.0.3.0/24'), IPAddress('::'), IPNetwork('fe80::/64')]
IP地址分类
IP地址有许多分类,并不是每个ip地址都能够做为主机地址。
单播地址(Unicast)
In [25]: IPAddress('192.0.2.1').is_unicast()Out[25]: TrueIn [26]: IPAddress('fe80::1').is_unicast()Out[26]: True
多播地址(Multicast)
In [27]: IPAddress('239.192.0.1').is_multicast()Out[27]: TrueIn [28]: IPAddress('ff00::1').is_multicast()Out[28]: True
私有地址(Private)
In [29]: IPAddress('172.24.0.1').is_private()Out[29]: TrueIn [30]: IPAddress('10.0.0.1').is_private()Out[30]: TrueIn [31]: IPAddress('192.168.0.1').is_private()Out[31]: TrueIn [32]: IPAddress('fc00::1').is_private()Out[32]: True
保留地址(Reserved)
In [33]: IPAddress('253.0.0.1').is_reserved()Out[33]: True
公网地址(Public)
In [34]: ip = IPAddress('62.125.24.5')In [35]: ip.is_unicast() and not ip.is_private()Out[35]: True
子网掩码(Netmasks)与主机掩码(Hostmasks)
In [36]: IPAddress('255.255.254.0').is_netmask()Out[36]: TrueIn [37]: IPAddress('0.0.1.255').is_hostmask()Out[37]: True
回环地址(loopback)
In [38]: IPAddress('127.0.0.1').is_loopback()Out[38]: TrueIn [39]: IPAddress('::1').is_loopback()Out[39]: True
IP地址比较
IPAddress对象还可以进行彼此比较。IPAdrees可以代表某个具体的ip地址,也可以代表某个只有单个主机的网络,因此在比较ip地址之前,应转换成同一类型,以避免出现奇怪的结果。
In [42]: IPAddress('192.0.2.1') == IPAddress('192.0.2.1')Out[42]: TrueIn [43]: IPAddress('192.0.2.1') < IPAddress('192.0.2.2')Out[43]: TrueIn [44]: IPAddress('192.0.2.1') <= IPAddress('192.0.2.1')Out[44]: TrueIn [45]: IPAddress('192.0.2.1') <= IPAddress('192.0.2.2')Out[45]: True
而对于IPNetwork而言,比较的是两个子网而非两个ip地址:
In [46]: IPNetwork('192.0.2.0/24') == IPNetwork('192.0.2.112/24')Out[46]: True若要比较其ip,则只需取其ip属性即可:
In [47]: IPNetwork('192.0.2.0/24').ip == IPNetwork('192.0.2.112/24').ipOut[47]: FalseIn [48]: IPNetwork('192.0.2.0/24').ip < IPNetwork('192.0.2.112/24').ipOut[48]: True或者直接明确比较cidr网络地址:
<pre name="code" class="plain">In [49]: IPNetwork('192.0.2.0/24').cidr == IPNetwork('192.0.2.112/24').cidrOut[49]: True注意:IPAddress(标量)和IPNetwork(向量)不能直接比较,如果非要比较的话,则要具体指明IPNetwork的哪个值。比如:
In [50]: IPAddress('192.0.2.0') == IPNetwork('192.0.2.0/32')[0]Out[50]: TrueIn [51]: IPAddress('192.0.2.0') == IPNetwork('192.0.2.0/32')[-1]Out[51]: TrueIn [52]: IPAddress('192.0.2.0') != IPNetwork('192.0.2.0/32')[0]Out[52]: False
非标准IP分布
如果要要得到从IP地址A到IP地址B之间的网络,那么需要计算CIDR或子网地址,这无疑是件痛苦的事情。而netaddr提供一种很好的解决方法。
In [55]: r1 = IPRange('192.0.2.1', '192.0.2.15')In [56]: r1.cidrs()Out[56]: [IPNetwork('192.0.2.1/32'), IPNetwork('192.0.2.2/31'), IPNetwork('192.0.2.4/30'), IPNetwork('192.0.2.8/29')]下面是IPRange和IPNetwork之间的比较:
In [58]: IPRange('192.0.2.0', '192.0.2.255') != IPNetwork('192.0.2.0/24')Out[58]: FalseIn [59]: IPRange('192.0.2.0', '192.0.2.255') == IPNetwork('192.0.2.0/24')Out[59]: True如果想要得到IPRange中的IP地址,则用list:
In [60]: r1 = IPRange('192.0.2.1', '192.0.2.15')In [61]: addrs = list(r1)In [62]: addrsOut[62]: [IPAddress('192.0.2.1'), IPAddress('192.0.2.2'), IPAddress('192.0.2.3'), IPAddress('192.0.2.4'), IPAddress('192.0.2.5'), IPAddress('192.0.2.6'), IPAddress('192.0.2.7'), IPAddress('192.0.2.8'), IPAddress('192.0.2.9'), IPAddress('192.0.2.10'), IPAddress('192.0.2.11'), IPAddress('192.0.2.12'), IPAddress('192.0.2.13'), IPAddress('192.0.2.14'), IPAddress('192.0.2.15')]In [63]: r1 == addrsOut[63]: False强调一点,若要比较,必须是同类型的才行(才有意义)。但是如果有一个序列包含IPAddress、IPNetwork和string类型的ip地址时该怎么办?IPSet类可以处理IP地址和网络组成的组。
In [64]: ips = [IPAddress('192.0.2.1'), '192.0.2.2/31', IPNetwork('192.0.2.4/31'), IPAddress('192.0.2.6'), IPAddress('192.0.2.7'), '192.0.2.8', '192.0.2.9', IPAddress('192.0.2.10'), IPAddress('192.0.2.11'), IPNetwork('192.0.2.12/30')]In [67]: s1 = IPSet(r1.cidrs())In [68]: s2 = IPSet(ips)In [69]: s1Out[69]: IPSet(['192.0.2.1/32', '192.0.2.2/31', '192.0.2.4/30', '192.0.2.8/29'])In [70]: s2Out[70]: IPSet(['192.0.2.1/32', '192.0.2.2/31', '192.0.2.4/30', '192.0.2.8/29'])In [71]: s1 == s2Out[71]: True那么当从IPSet中移除一个元素,看看会发生什么事情:
In [72]: s2.pop()Out[72]: IPNetwork('192.0.2.4/30')In [73]: s1 == s2Out[73]: False更多IPSet教程请参看官网教程。另一种是使用Glob方法表示IP范围,即模式匹配的方法来表示IP地址范围。例如:
In [75]: IPGlob('192.0.2.*') == IPNetwork('192.0.2.0/24')Out[75]: True由于IPGlob是IPRange的一个子类,所以IPRange的所有方法都适合于IPGlob,IPGlob暂时只适用于IPv4。
0 0
- python获取ip地址
- Python获取ip地址
- Python获取IP地址
- python获取网卡IP地址
- 用python获取本地的ip地址
- Python获取本机IP地址
- Python获取本机Ip地址
- python 获取linux 本机IP地址
- python获取局域网内计算机IP地址
- python 获取主机mac ip地址
- python获取远程设备的IP地址
- Python获取本机Ip地址
- Python 获取本机ip地址
- Python+socket获取本机IP地址
- python 获取网卡名称及其IP地址
- 通过 python 获取本机IP地址
- Python获取本机所有IP地址
- Python获取本机所有IP地址
- Curl命令
- 为iPhone 6设计自适应布局
- Softmax公式推导
- UNIX环境高级编程-第10章- 信号 - 二
- 2014-12-25
- Python获取ip地址
- ECCO爱步-让行走成为一种乐趣
- Oracle时间加减
- js中身份证的正则表达式
- 你怎么对待婚姻,婚姻就怎么对待你!
- Android 文件读写到命名空间的文件夹(简单)
- 基于PHP的cURL快速入门
- GIT分支管理是一门艺术
- Spring学习1-初识Spring