python操作 linux連接wifi,查看wifi連接狀態方法


Python連接Ubuntu 環境 wifi流程

 

1、獲取網絡接口列表

通過wifi_net.py 的query_net_cards方法獲取終端物理網絡接口列表及IP信息: 獲取物理網絡接口列表:

ls -d /sys/class/net/*/device | cut -d/ -f5
或者:
find /sys/class/net -type l -not -lname '*virtual*' -printf '%f\n'
iwifconfig

代碼示例:

# 查詢所有物理網卡
    def _query_net_card_info(if_name):
        net_card_info = {
            "mac": "",
            "type": "eth",
            "ip": "",
            "netmask": "",
        }
        try:
            net_info = netifaces.ifaddresses(if_name)
        except ValueError:
            logger.error("No such interface: %s" % if_name)
            return net_card_info
        # 如果為無線網卡,將修改網卡類型為wlan
        if if_name in common.cmd_excute("iw dev | awk '$1==\"Interface\" {print $2}'"):
            net_card_info["type"] = "wlan"

        net_card_info["mac"] = net_info[netifaces.AF_LINK][0]["addr"].upper()
        ipv4_info = net_info.get(netifaces.AF_INET)
        if ipv4_info:
            net_card_info["ip"] = ipv4_info[0]["addr"]
            net_card_info["netmask"] = ipv4_info[0]["netmask"]
        return net_card_info

    @staticmethod
    def query_net_cards():
        """
        {
        "enp2s0":       // 接口名稱
            {
                "mac": "98:FA:9B:99:E5:6A",      // MAC地址
                "type": "eth",                  // 接口類型,eth-有線網卡, wlan-無線網卡
                "ip": "192.168.2.90",           // 接口當前IP
                "netmask": "255.255.255.0",     // 接口掩碼
                "dns":"192.168.2.1",            // dns服務器ip
                "gateway": "192.168.2.1"         // 網管地址
            },
        "wlan0":
            {
                "mac": "98:FA:9B:99:E5:6A",      // MAC地址
                "type": "wlan",                 // 接口類型,eth-有線網卡, wlan-無線網卡
                "ip": "",                       // 接口當前IP
                "netmask": "",                  // 接口掩碼
                "dns":"192.168.2.1",            // dns服務器ip
                "gateway": "192.168.2.1"        // 網管地址
            }
        }
        """
        net_cards = dict()
        # 獲取所有物理網卡名稱
        command = "ls -d /sys/class/net/*/device | cut -d/ -f5"
        interfaces = common.cmd_excute(command)

        # 獲取dns服務器ip
        dns_path = '/etc/resolv.conf'
        dns_list = []
        if os.path.exists(dns_path):
            dns_list = common.cmd_excute("cat %s|grep ^nameserver|awk '{print $2}'" % dns_path, b_print=False)
        # 獲取網管地址
        gateways = netifaces.gateways().get('default').get(netifaces.AF_INET)

        for interface in interfaces:
            net_card = Network._query_net_card_info(if_name=interface)
            net_card["dns"] = dns_list if dns_list else ""
            net_card["gateway"] = gateways[0] if gateways else ""
            net_cards[interface] = net_card
        return net_cards

2、獲取無線網絡列表
通過wifi_net.py 的query_wifi_ssids方法獲取掃描到的無線網絡列表:

掃描無線網絡:
通過iwlist 命令獲取,需要解析命令行輸出:

iwlist wlan0 scan

或,通過python庫 wifi解析:

        def query_wifi_ssids(wifi_if):
        import wifi
        import codecs
        ssid_list = []
        try:
            common.cmd_excute("ifconfig %s up" % wifi_if)
            cell_list = wifi.Cell.all(wifi_if)
        except wifi.exceptions.InterfaceError as e:
            # 可能非Wifi接口
            logger.error("_get_wireless_ssid_list exception: %s" % traceback.format_exc())
            return ssid_list

        for cell in cell_list:
            ssid_list.append(
                {
                    "ssid": codecs.utf_8_decode(cell.ssid)[0].encode('utf-8'),
                    "mac": cell.address,
                    "encrypted": cell.encrypted,
                    "quality": cell.quality,
                    # "signal": cell.signal,
                }
            )

        return ssid_list

返回數據示例:

[
        {
            "ssid": "leifeng_2",             // 無線網絡SSID
            "mac": "58:D9:D5:D3:FB:01",    // 無線接入點MAC
            "enctypted": True,              // 是否加密
             "quality": cell.quality     //信號強度
        },
        {
            "ssid": "leifeng_2_5G",
            "mac": "58:D9:D5:D3:FB:05",
            "enctypted": True,
             "quality": cell.quality     
        }
    ]

3、連接無線網絡,檢查連接結果
connect_wifi方法連接無線網絡:

# 配置無線網絡:
wpa_passphrase "leifeng_2" "radeon123" > /etc/wpa_supplicant/wpa_supplicant.conf
# leifeng_2網絡名稱   radeon123 wifi密碼
# 連接無線網絡:
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf &
# -B后台執行
    # 代碼示例
    def connect_wifi(net_card, ssid, password, static_ip=""):
        """連接wifi"""
        wifi_conf_command = 'wpa_passphrase "%s" "%s" > /etc/wpa_supplicant/wpa_supplicant.conf' % (ssid, password)
        common.cmd_excute(wifi_conf_command)

        wifi_conn_command = 'wpa_supplicant -i %s -c /etc/wpa_supplicant/wpa_supplicant.conf -B > /tmp/wifi_conn.txt' % net_card
        logger.debug("Start wifi connection: %s " % wifi_conn_command)
        common.cmd_excute(wifi_conn_command)
        if not static_ip:
            # flush
            flush_command = "ip addr flush dev %s" % net_card
            common.cmd_excute(flush_command)
            # 自動分配ip地址
            auto_command = "dhclient %s" % net_card
            common.cmd_excute(auto_command)
        else:
            # 配置靜態ip
            manual_common = "ifconfig %s %s" %(net_card,static_ip)
            common.cmd_excute(manual_common)
        for i in range(10):
            wifi_status_command = "cat /sys/class/net/{}/operstate".format(net_card)
            wifi_status_process = subprocess.Popen(wifi_status_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
            if wifi_status_process.stdout.readline() == "up":
                logger.debug("wifi %s connection success") % ssid
                break
            time.sleep(1)
        else:
            wifi_result_command = "cat /tmp/wifi_conn.txt | grep reason=WRONG_KEY"
            wifi_result_process = subprocess.Popen(wifi_result_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                                             shell=True)
            if wifi_result_process.stdout.readline():
                logger.debug("wifi %s connection fail,password error") % ssid
                return False,"password error"
            logger.debug("wifi %s connection timeout") % ssid
            return False,"connect timeout"
        return True,"success"

4、封裝cmd命令

定義common.py文件,

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/11/11 下午3:21
import subprocess

def shell_excute(rsyncStr, shell=False, b_print=True):
    p = subprocess.Popen(rsyncStr, shell=shell,
                         stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output = "".join(p.communicate())
    return output

def cmd_excute(command, b_trip=True, b_print=True):
    ret_list = []
    cmd_ret = shell_excute(command, shell=True, b_print=b_print).splitlines()
    if b_trip:
        for sline in cmd_ret:
            if len(sline.strip()) != 0:
                ret_list.append(sline.strip())
    else:
        ret_list = cmd_ret
    return ret_list

 

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM