Python3 获取本地IP

本文介绍了一个Python脚本,用于列出本地可用的IPv4网络接口、检查接口状态、判断地址是否在同一子网,并根据需求筛选能连接互联网的适配器。通过示例展示了如何获取本地设备的适配器信息并选择合适的IP地址。
摘要由CSDN通过智能技术生成

 

# !/usr/bin/python3
# coding: utf-8
import os
import random
import sys

import IPy
import certifi
import netifaces
import pycurl


def list_ipv4_adapter():
    mapping = {}
    gateways = netifaces.gateways()
    if netifaces.AF_INET in gateways:
        ipv4gates = gateways[netifaces.AF_INET]
        for gate in ipv4gates:
            mac = gate[1][1:-1]
            mapping[mac] = gate[0]

    ipv4list = []
    macs = netifaces.interfaces()
    for mac in macs:
        adapter = netifaces.ifaddresses(mac)
        if netifaces.AF_INET not in adapter:
            continue

        ipv4group = adapter[netifaces.AF_INET]
        if len(ipv4group) < 1:
            # IPv4 is not enabled or configured
            continue

        # len(ipv4group) > 1
        # One available network adapter is configured with multiple network segments

        mac = mac[1:-1]
        for ipv4 in ipv4group:
            ip = ipv4['addr']
            mask = ipv4['netmask']
            # `broadcast` may be the upper limit address of this network segment
            gate = mapping[mac] if mac in mapping else ipv4['broadcast']

            ipv4list.append((ip, mask, gate, mac))
    # [('127.0.0.1', '255.0.0.0', '127.255.255.255', 'DFCA0DEC-A7BA-11EB-A168-806E6F6E6963')]
    return ipv4list


def is_adapter_up(ip):
    """
    ip like 127.0.0.1
    """
    if 'win32' == sys.platform:
        cmd = 'ipconfig |findstr "%s"'
        # Using `ipconfig -all` to show all, includes not running
    elif 'linux' == sys.platform:
        cmd = 'ifconfig |grep "%s"'
        # Using `ifconfig -a` to show all, includes not running
        # Using `ifconfig NAME up` to start
        # Using `ifconfig NAME down` to close
    else:
        print('Unsupported system type %s' % sys.platform)
        return False

    with os.popen(cmd % ip, 'r') as f:
        if '' != f.read():
            # UP and RUNNING
            return True
        else:
            print('Network adapter %s is not running' % ip)
            return False


def in_same_segment(ip, mask, addr):
    """
    ip like 127.0.0.1
    mask like 255.0.0.0
    addr like 192.168.1.1
    """
    # Specifies whether the address is in the network segment
    if '' == addr.strip():
        return True

    subnet = IPy.IP('%s/%s' % (ip, mask), make_net=True)
    if addr not in subnet:
        print('Address %s is not in the segment of %s' % (addr, subnet))
        return False
    return True


def usable_ipv4_adapter(ipv4list, addr=''):
    """
    ipv4list like [('127.0.0.1', '255.0.0.0', '127.255.255.255', 'DFCA0DEC-A7BA-11EB-A168-806E6F6E6963')]
    addr like 192.168.1.1
    """
    if '' != addr.strip():
        iterator = filter(lambda item: in_same_segment(item[0], item[1], addr), ipv4list)
        ipv4list = list(iterator)

        if len(ipv4list) < 1:
            return []

    iterator = filter(lambda item: is_adapter_up(item[0]), ipv4list)
    return list(iterator)


def ping_to_website(website, interface):
    """
    website like https://www.baidu.com/
    interface like 127.0.0.1
    """
    c = pycurl.Curl()
    try:
        c.setopt(pycurl.URL, website)
        c.setopt(pycurl.CAINFO, certifi.where())  # for https, also supported HTTP
        c.setopt(pycurl.USERAGENT, "Chrome/91.0.4472.77")
        c.setopt(pycurl.FOLLOWLOCATION, 1)
        c.setopt(pycurl.MAXREDIRS, 5)
        c.setopt(pycurl.CONNECTTIMEOUT, 1)
        c.setopt(pycurl.TIMEOUT, 1)  # too strict
        if interface:
            c.setopt(pycurl.INTERFACE, interface)

        c.setopt(pycurl.WRITEFUNCTION, lambda i: None)  # avoid print too much
        c.perform()  # default to print HTML content
        code = c.getinfo(pycurl.HTTP_CODE)
        if 200 == code:
            return True
        return False
    except pycurl.error as e:
        return False
    finally:
        if c:
            c.close()


def ping_to_internet(interface):
    """
    interface like 127.0.0.1
    """
    websites = ['https://www.baidu.com/', 'https://www.google.com.hk/']
    for website in websites:
        if ping_to_website(website, interface):
            print('Network adapter %s can connect to the Internet' % interface)
            return True
    return False


def internet_ok_adapter(ipv4list):
    """
    ipv4list like [('127.0.0.1', '255.0.0.0', '127.255.255.255', 'DFCA0DEC-A7BA-11EB-A168-806E6F6E6963')]
    """
    iterator = filter(lambda item: ping_to_internet(item[0]), ipv4list)
    return list(iterator)


def local(addr='', internet=False):
    """
    addr like 192.168.1.1
    internet is boolean
    """
    print()
    # The available local IP address in the same network segment as the specified web address
    ipv4adapters = list_ipv4_adapter()
    if len(ipv4adapters) < 1:
        print('0 IPv4 network adapter were found')
        return ''

    print('%s IPv4 network adapter were found:' % len(ipv4adapters))
    for i, adapter in enumerate(ipv4adapters):
        print(
            ' [%s] IP: %s, NetMask: %s, GateWay: %s, MAC: %s' % (i + 1, adapter[0], adapter[1], adapter[2], adapter[3]))

    ipv4adapters = usable_ipv4_adapter(ipv4adapters, addr)
    if len(ipv4adapters) < 1:
        print('0 IPv4 network adapter are unavailable')
        return ''

    if internet:
        ipv4adapters = internet_ok_adapter(ipv4adapters)
        if len(ipv4adapters) < 1:
            print('0 IPv4 network adapter able to connect Internet')
            return ''

    if len(ipv4adapters) == 1:
        ip, mask, gate, mac = ipv4adapters[0]
        print('Only one network adapter is qualified:')
    else:
        # 1. Multiple network adapter available
        #    Network segments between adapters cannot overlap
        # 2. One available network adapter is configured with multiple network segments
        #    Network segments of the same adapter can overlap
        ip, mask, gate, mac = random.choice(ipv4adapters)
        print('Multiple network adapter are available, randomly select one:')

    print(' IP: %s, NetMask: %s, GateWay: %s, MAC: %s' % (ip, mask, gate, mac))
    return ip


def access(port):
    if port < 1024 or 65535 < port:
        # privileged port
        # out of range
        return False

    if 'win32' == sys.platform:
        cmd = 'netstat -aon|findstr ":%s "' % port
    elif 'linux' == sys.platform:
        cmd = 'netstat -aon|grep ":%s "' % port
    else:
        print('Unsupported system type %s' % sys.platform)
        return False

    with os.popen(cmd, 'r') as f:
        if '' != f.read():
            print('Port %s is occupied' % port)
            return False
        else:
            return True


if __name__ == "__main__":
    print('The IP address of this device is %s' % local('', True))
    print('The IP address of this device is %s' % local('172.17.0.1', False))

 

 

一次执行输出示例:


4 IPv4 network adapter were found:
 [1] IP: 172.17.0.1, NetMask: 0.0.0.0, GateWay: 255.255.255.255, MAC: 12A34BCD-5EFG-6789-H0IG-12K34LM567N8
 [2] IP: 10.20.30.40, NetMask: 255.255.255.255, GateWay: 10.20.30.40, MAC: 901234O5-PQ67-8901-R23S-456T7U89VW01
 [3] IP: 192.168.1.1, NetMask: 255.255.255.255, GateWay: 192.168.1.254, MAC: X23YZ4AB-56CD-7890-1E23-45F6GHIJ7890
 [4] IP: 127.0.0.1, NetMask: 255.0.0.0, GateWay: 127.255.255.255, MAC: KLMN1OPQ-R2ST-34UV-W567-890X1Y2Z3456
Network adapter 127.0.0.1 is not running
Network adapter 172.17.0.1 can connect to the Internet
Network adapter 192.168.1.1 can connect to the Internet
Multiple network adapter are available, randomly select one:
 IP: 192.168.1.1, NetMask: 255.255.255.255, GateWay: 192.168.1.254, MAC: X23YZ4AB-56CD-7890-1E23-45F6GHIJ7890
The IP address of this device is 192.168.1.1

4 IPv4 network adapter were found:
 [1] IP: 172.17.0.1, NetMask: 0.0.0.0, GateWay: 255.255.255.255, MAC: 12A34BCD-5EFG-6789-H0IG-12K34LM567N8
 [2] IP: 10.20.30.40, NetMask: 255.255.255.255, GateWay: 10.20.30.40, MAC: 901234O5-PQ67-8901-R23S-456T7U89VW01
 [3] IP: 192.168.1.1, NetMask: 255.255.255.255, GateWay: 192.168.1.254, MAC: X23YZ4AB-56CD-7890-1E23-45F6GHIJ7890
 [4] IP: 127.0.0.1, NetMask: 255.0.0.0, GateWay: 127.255.255.255, MAC: KLMN1OPQ-R2ST-34UV-W567-890X1Y2Z3456
Address 172.17.0.1 is not in the segment of 10.20.30.40
Address 172.17.0.1 is not in the segment of 192.168.1.1
Address 172.17.0.1 is not in the segment of 127.0.0.1
Only one network adapter is qualified:
 IP: 172.17.0.1, NetMask: 0.0.0.0, GateWay: 255.255.255.255, MAC: 12A34BCD-5EFG-6789-H0IG-12K34LM567N8
The IP address of this device is 172.17.0.1

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值