一、微信登录调用sns/userinfo取用户信息时nickname中文乱码巨坑问题解决
在使用微信扫码登录第三方应用时,第三方在取得access_token之后需要调用微信的sns/userinfo接口获取用户的nickname,openid之类的数据内容。然而在使用微信接口的时候发现真是有巨坑。
一开始我用的是英文昵称的微信号,扫码登录一切正常,但在使用一个中文昵称的微信扫码后,崩了。本来我以为只是一个简单的字符编码问题,但开始处理之后发现你要一开始不知道,它还真是个麻烦事,而这将会伴随每一个使用微信登录的开发者。
微信请求方式http请求方式: GET
https://api.weixin.qq.com/sns/userinfo?lang=zh_CN&access_token=ACCESS_TOKEN&openid=OPENID
response = requests.get(url, timeout=3)
在拿到response之后,我通过response.json提取到对应的数据json信息,英文下都正常,但是使用中文微信昵称后,我试了很多方法,都没法从这个json里面拿到正确的中文昵称。nickname转来转去都是乱码。
{"openid":"o1jBH6CRXOyii8BHRxDB0g9Kv3Jg","nickname":"è¯è¯ä¸ª","sex":0,}
'nickname': b'\xc3\xa8\xc2\xaf\xc2\x95\xc3\xa8\xc2\xaf\xc2\x95\xc3\xa4\xc2\xb8\xc2\xaa',
UnicodeEncodeError: 'gbk' codec can't encode character '\xaf'
nickname': 'è
解决办法:有网友说微信是使用的ISO-8859-1编码,先用‘ISO-8859-1’进行编码,再用‘UTF-8’进行解码,但在response.json中我仍未成功取到nickname.问题的讨论。更可误的是微信的接口文档里也不对这一块进行说明,真是可恨,让每个开发者都浪费时间在这个无聊的问题上。除了response.json外,response.text提取到的数据也是一样有问题。
真正解决问题的办法,是通过 response.content 来得取返回内容,而不要用response.text或response.json来提取(微信也微信,真是让人蛋痛!)。或者使用response.text来取得内容,然后使用:response.text.encode('iso-8859-1').decode('utf8') 进行处理,这样后面的内容也就都正常了。
二、Windows下命令行运行PHP时cmd窗口中文乱码问题
习惯了在linux下使用定时任务和运行php的cli命令,实际在windows下运行CLI也是很方便的事,我这里使用的是Visual NMP x64版本,安装选用的PHP7.1版本,直接找到PHP文件包的地址在cmd命令行中使用php.exe执行即可,不过在使用时发现执行结果里中文显示都是乱码,确实不爽,怎么解决,很方便:
1.临时解决办法:
在cmd窗口中运行chcp 65001,执行之后,cmd的编码格式就是UTF-8,chcp 65001是什么意思呢?CHCP是一个计算机指令,能够显示或设置活动代码页编号。其中65001就是UTF-8代码页;950繁体中文;936简体中文默认的GBK;437 MS-DOS美国英语。这种修改只能在当前打开的窗口中有效。
2.永久更改cmd编码值需要修改注册表
运行regedit,找到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor,右键-新建,选择字符串值,名称列填写autorun, 数值数据填写chcp 65001。
3.使用reg执行文件永久更改
新建一个cmd.reg文件,内容粘贴如下内容之后运行即可:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe]
"CodePage"=dword:0000fde9
"FontFamily"=dword:00000036
"FontWeight"=dword:00000190
"FaceName"="Consolas"
"ScreenBufferSize"=dword:232900d2
"WindowSize"=dword:002b00d2
三、服务器僵尸进程(zombie进程)的处理
某次上服务器使用top一看,第二行显示1 zombie,没过一会儿再一看,显示有2 个zombie。非常好奇。因为接触服务器这么多年,虽然一直知道zombie进程,但真的没有见过服务器出现过zombie进程。查看僵尸进程的命令如下:
#查看僵尸进程,运行结果参考如下
u007@ndd2:~$ ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]'
Z 12334 12339 /path/cmd
Zs 2512326 3849523 [python] <defunct>
u007@ndd2:~$ ps -Ao stat,pid,user,fname,tmout,f,wchan,command | grep -i ^z
Z 2548926 ? root cpulimit - 0 - [cpulimit] <defunct>
选项说明:
-A 列出所有进程
-o 自定义输出字段 我们设定显示字段为 stat(状态), ppid(进程父id), pid(进程id),cmd(命令)这四个参数。因为状态为 z或者Z的进程为僵尸进程,所以我们使用grep抓取stat状态为zZ开头的进程。还有其它很多好用的参数,比如user,command.command显示的命令比cmd完整。
找到僵尸进程后我们可以使用 kill -HUP 进程ID 来杀掉,然后再使用命令查找确认僵尸进程是否已被杀死。如果kill 子进程的无效,可以尝试kill 其父进程来解决问题。不过很多僵尸进程都很难kill掉.得找到原头再去处理。