Python获取Windows计算机内已存储的WiFi密码

所需环境、工具

  • Windows系统
  • Python3
  • PyCharm
  • Subprocess模块
  • Locale模块

实现思路

  • 通过 Locale 模块查询系统默认语言,根据系统不同语言规定不同的正则匹配规则
  • 通过 Subprocess 模块执行命令行语句,自动化netsh wlan show profiles的查询过程
  • 通过之前设置好的正则匹配规则,获取 WiFi 名称与密码

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

# 查看系统默认语言
import locale
# 控制命令行
import subprocess
import re

loc_lang = locale.getdefaultlocale()
# [Out]: ('zh_CN', 'cp936')
# cp936 即为 GBK 编码,IBM在发明 Code Page 的时候将 GBK 放在第936页,因此 GBK 也被称为 cp936

# 根据不同的系统默认语言,规定不同的正则表达式提取规则,若为中英文以外的其他语言,则需更改匹配语句
if loc_lang[0] == "zh_CN":
re_pattern = [
"所有用户配置文件 : (.*)\r",
"安全密钥 : 不存在\r",
"关键内容 : (.*)\r"
]
else:
re_pattern = [
"All User Profile : (.*)\r",
"Security key : Absent\r",
"Key Content : (.*)\r"
]

# 等价于在命令行中输入 netsh wlan show profiles
# 将默认的 capture_output=False 设为 True,则 stdout 和 stderr 将会被捕获
# 在解码时,一定要添加 errors="ignore" 的命令,否则会由于解码条件过于严格而报错
cmd_output = subprocess.run(["netsh", "wlan", "show", "profiles"], capture_output=True).stdout.decode(loc_lang[1], errors="ignore")

# 获取所有 WiFi 名称
wifi_names = re.findall(re_pattern[0], cmd_output)

# 总列表
wifi_list = []
if len(wifi_names) != 0:
for wifi in wifi_names:
# 将单个 WiFi 名称与密码存入字典
wifi_info = {}
# 添加 WiFi 名称入字典
wifi_info["ssid"] = wifi
# 添加WiFi名称与命令参数 "key=clear" 显示 WiFi 密码
cmd_wifi_info = subprocess.run(["netsh", "wlan", "show", "profiles", wifi, "key=clear"], capture_output=True).stdout.decode(loc_lang[1], errors="ignore")
# 判断密码是否存储在计算机里,若否,则密码填为 None
# 如校园网、部分酒店 WiFi 等需要通过进行身份认证而登录的 WiFi ,其密码不会存储在计算机里
if re.search(re_pattern[1], cmd_wifi_info):
# 若在 WiFi 总列表中不想显示这种 WiFi ,将此行语句替换成 continue 即可
wifi_info["password"] = None
# 若显示密码存在,提取密码,填入字典
else:
password = re.findall(re_pattern[2], cmd_wifi_info)
if password == []:
wifi_info["password"] = None
else:
wifi_info["password"] = password[0]
# 将各字典填入总列表
wifi_list.append(wifi_info)

for i in range(len(wifi_list)):
print(wifi_list[i])

执行结果

WiFi_Stored