我正在尝试用Python 3编写脚本,但是今天可用的所有模块都可以在python 2上运行,这将使我能够搜索无线网络并连接到它们。是否有任何Python 3库?
我为python 2尝试过的代码
from wireless import Wireless
wireless = Wireless()
wireless.connect(ssid='ssid', password='password')
这给我一个错误
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\Himanshu Poddar\AppData\Local\Programs\Python\Python36-32\lib\site-packages\wireless\Wireless.py", line 23, in __init__
self._driver_name = self._detectDriver()
File "C:\Users\Himanshu Poddar\AppData\Local\Programs\Python\Python36-32\lib\site-packages\wireless\Wireless.py", line 50, in _detectDriver
compare = self.vercmp(ver, "0.9.9.0")
File "C:\Users\Himanshu Poddar\AppData\Local\Programs\Python\Python36-32\lib\site-packages\wireless\Wireless.py", line 71, in vercmp
return cmp(normalize(actual), normalize(test))
NameError: name 'cmp' is not defined
但是这不起作用,因为它基于python2。有没有办法使用Python 3连接到wifi?
答案 0 :(得分:3)
成为图书馆的迫切需要吗?无需一个即可轻松实现(或将其另存为模块并导入)。
如果无线接口为wlan
,并且SSID和配置文件名称相同(通常为true),则只需使用
cmd = "netsh wlan connect name={0} ssid={0}".format(tt)
k = subprocess.run(cmd, capture_output=True, text=True).stdout
在上面的代码段中,tt
是您要连接的SSID的名称-这是我的代码中的变量,因为它依次连接到不同的SSID。
我知道使用subprocess
有点麻烦,但是上面的代码片段并没有增加任何可观的开销。
这是我编写的脚本的一部分,该脚本用于“收集”父母父母的太阳能逆变器中的数据:逆变器具有自己的SSID,因此该脚本必须依次连接到每个逆变器。使用requests
获取实时数据;将数据存储在PostgreSQL数据库中;然后重新连接到家用wifi。
我知道设备还存储历史数据,但是制造商在2018年左右禁用了数据API,以带动所有者转向其应用程序(因此向他们提供了打包和出售的用户数据)。
答案 1 :(得分:2)
要在Windows中使用python连接wifi,更好的选择是使用 winwifi 模块:
我建议您在安装winwifi之前先安装铅锤。 这是下载铅锤的链接:https://pypi.org/project/plumbum/
从此处安装Winwifi后:https://pypi.org/project/winwifi/ 最好将其安装在32位python文件夹中。
安装后,您可以通过以下代码检查模块:
import winwifi
winwifi.WinWiFi.connect('the_exact_ssid_or_name_of_your_known_wifi_router')
在IDLE上运行此代码时,您会看到wifi已连接到设备。 如果要连接新设备,可以在添加配置文件后使用代码:
import winwifi
winwifi.WinWiFi.addprofile('ssid_of_router')
winwifi.WinWiFi.connect('the_ssid_of_router', 'password')
您可以使用以下命令断开当前的Wifi连接:
import winwifi
winwifi.WinWiFi.disconnect()
此模块上还有更多命令,请尝试对其进行探索。 只需参考winwifi文件夹中的 main.py 文件即可。
答案 2 :(得分:1)
注释(约[PyPI]: wireless 0.3.2]):
因此,我建议寻找替代方案:
好的,经过大量浏览:
,我能够提出一些建议。
code.py :
#!/usr/bin/env python3
import sys
import time
import ctypes
import comtypes
import traceback
from win32wifi import Win32Wifi as ww
ERROR_SUCCESS = 0
WLAN_CONNECTION_HIDDEN_NETWORK = 0x00000001
class WLANException(Exception): pass
class ConnectCallbackContext(ctypes.Structure):
_fields_ = [
("guid", ctypes.c_wchar_p),
("start", ctypes.c_byte),
("end", ctypes.c_byte),
("fail", ctypes.c_byte),
]
def _wlan_connect_callback(data, context_addr):
if context_addr:
context = ConnectCallbackContext.from_address(context_addr)
if str(data.interfaceGuid) == context.guid and data.notificationSource == ww.WLAN_NOTIFICATION_SOURCE_DICT[ww.WLAN_NOTIFICATION_SOURCE_ACM]:
if data.notificationCode == ww.WLAN_NOTIFICATION_ACM_ENUM.wlan_notification_acm_connection_start.name:
context.start += 1
elif context.start:
if data.notificationCode == ww.WLAN_NOTIFICATION_ACM_ENUM.wlan_notification_acm_connection_complete.name:
context.end += 1
elif data.notificationCode == ww.WLAN_NOTIFICATION_ACM_ENUM.wlan_notification_acm_connection_attempt_fail.name:
context.fail += 1
def wireless_connect(
ssid,
password,
timeout=15, # secs
authentication="WPA2PSK", # "open",
encryption="AES", # "WEP",
key_type="passPhrase", # "networkKey",
interface_index=0, # Don't modify this (until PCs with more than 1 WLAN adapter arise :) )
):
interfaces = ww.getWirelessInterfaces()
if interface_index < 0 or len(interfaces) < interface_index:
raise WLANException(-1, "No WLAN interface for given index")
interface = interfaces[interface_index]
profile_name = ssid + "_profile_tmp"
ssid_hex = "".join((hex(ord(c))[2:] for c in ssid)).upper()
profile_string = f"""<?xml version=\"1.0\"?>
<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">
<name>{profile_name}</name>
<SSIDConfig>
<SSID>
<hex>{ssid_hex}</hex>
<name>{ssid}</name>
</SSID>
</SSIDConfig>
<connectionType>ESS</connectionType>
<connectionMode>manual</connectionMode>
<MSM>
<security>
<authEncryption>
<authentication>{authentication}</authentication>
<encryption>{encryption}</encryption>
<useOneX>false</useOneX>
</authEncryption>
<sharedKey>
<keyType>{key_type}</keyType>
<protected>false</protected>
<keyMaterial>{password}</keyMaterial>
</sharedKey>
</security>
</MSM>
</WLANProfile>
"""
connection_params = {
"connectionMode": "wlan_connection_mode_temporary_profile",
"profile": profile_string,
"ssid": None,
"bssidList": None,
"bssType": "dot11_BSS_type_infrastructure",
"flags": WLAN_CONNECTION_HIDDEN_NETWORK,
}
ctx = ConnectCallbackContext(interface.guid_string, 0, 0, 0)
notification_obj = ww.registerNotification(_wlan_connect_callback, context=ctypes.pointer(ctx))
try:
res = ww.connect(interface, connection_params)
except Exception as e:
ww.unregisterNotification(notification_obj)
raise WLANException("WlanConnect failed") from e
end_time = time.time() + timeout;
while time.time() < end_time:
time.sleep(0.5)
if ctx.end:
break
ww.unregisterNotification(notification_obj)
if ctx.end:
if ctx.fail:
raise WLANException(-2, "Connection failed")
else:
raise WLANException(-3, "Connection timed out")
return interface.guid_string
def wireless_disconnect(interface_guid): # Borrowed (and improved) this func from win32wifi.Win32Wifi, to avoid creting the interface when only its guid is required
handle = ww.WlanOpenHandle()
try:
ww.WlanDisconnect(handle, comtypes.GUID(interface_guid))
except Exception as e:
raise WLANException("WlanDisconnect failed") from e
finally:
ww.WlanCloseHandle(handle)
def main(argv):
if argv:
try:
guid = argv[0]
print("Disconnecting wireless interface {:s} ...".format(guid))
wireless_disconnect(guid)
except:
traceback.print_exc()
else:
try:
print("Connecting to wireless network ...")
ssid = "Network SSID" # ssid and pwd here are (deliberately) dummy
pwd = "Network password"
guid = wireless_connect(ssid, pwd)
print("Connected interface {:s}".format(guid))
except:
traceback.print_exc()
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main(sys.argv[1:])
print("\nDone.")
script.bat :
time <nul
ping www.google.com
"e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code.py
ping www.google.com
"e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code.py {0C58E048-BC0B-4D5F-A21F-FCD4E4B31806}
ping www.google.com
time <nul
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q056721759]> sopr.bat *** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages *** [prompt]> script.bat [prompt]> time 0<nul The current time is: 1:45:08.31 Enter the new time: [prompt]> ping www.google.com Ping request could not find host www.google.com. Please check the name and try again. [prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code.py Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32 Connecting to wireless network ... Connected interface {0C58E048-BC0B-4D5F-A21F-FCD4E4B31806} Done. [prompt]> ping www.google.com Pinging www.google.com [2a00:1450:400d:809::2004] with 32 bytes of data: Reply from 2a00:1450:400d:809::2004: time=11ms Reply from 2a00:1450:400d:809::2004: time=12ms Reply from 2a00:1450:400d:809::2004: time=12ms Reply from 2a00:1450:400d:809::2004: time=19ms Ping statistics for 2a00:1450:400d:809::2004: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 11ms, Maximum = 19ms, Average = 13ms [prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code.py {0C58E048-BC0B-4D5F-A21F-FCD4E4B31806} Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32 Disconnecting wireless interface {0C58E048-BC0B-4D5F-A21F-FCD4E4B31806} ... Done. [prompt]> ping www.google.com Ping request could not find host www.google.com. Please check the name and try again. [prompt]> time 0<nul The current time is: 1:45:12.82 Enter the new time:
注释:
time <nul
)只是为了在控制台中证明代码正在与无线网络连接/断开连接(并且我不是从连接)并行获胜)
time 0<nul
(在输出中)的“ 0 ”部分来自哪里 最重要的一个:由于 Win32Wifi 有问题,因此上述代码无法使用 OOTB >。我发现了2个在这种情况下致命(严重)的错误,以及其他一些较小的错误。
我刚刚提交了 [GitHub]: kedos/win32wifi - Fixes (some critical) and improvements 。不知道它的结果是什么(考虑不活动时间)。
作为替代,您可以下载补丁,然后在本地应用更改。检查[SO]: Run/Debug a Django application's UnitTests from the mouse right click context menu in PyCharm Community Edition? (@CristiFati's answer)(修补 utrunner 部分),了解如何在 Win 上应用补丁(基本上,每行以开头)一个“ +” 符号进入,以一个“-” 符号开头的每一行都熄灭)。我正在使用 Cygwin , btw 。