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