写在前面
跨年夜那天临时起意,想用vs code写一写python,上手练练,用时两天半,完成了一个小工具,真的明白了什么是写bug小能手,就算最终完成的版本,也还是不稳定,想着先记录一下,有时间想起来再改吧
面向百度编程——出自《小张学python语录》
整个过程用到挺多基础模块,但架不住我菜啊,全都是不懂就百度,七拼八凑的把功能实现了,真是了不起,叉会腰
一、安装模块
1.1修改python源
pip 是一个现代的,通用的 Python 包管理工具。提供了对 Python 包的查找、下载、安装、卸载的功能。
在使用过程中,python包体积不大,等一会,还可以接受,不过在安装pyqt5时候,要一天的时间,索性还是用国内的源吧
国内源大概有这些:
阿里云 http://mirrors.aliyun.com/pypi/simple/
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
豆瓣(douban) http://pypi.douban.com/simple/
清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
这里分为两种途径,一种是临时修改,一种是永久修改。很好理解。
临时:在最后增加-i选项,及python源
pip install scrapy -i https://pypi.tuna.tsinghua.edu.cn/simple
Linux永久:修改 ~/.pip/pip.conf (没有就创建一个), 内容如下:
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
Windows永久:直接在user目录中创建一个pip目录,如:C:\Users\xx\pip,新建文件pip.ini,内容如下
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
声明:我只是用了临时,永久修改需要测试,我记录一下,以后有需要可以回来找
1.2安装python模块
这里就简单列出来使用了哪些包,python版本用的3.8.3
requests——用来建立会话,post和get
os——处理文件
pillow——图片处理(主要用来处理验证码)
bs4——处理返回的网页数据
baidu-aip——使用百度智能云的接口进行验证码识别
pyqt5——python上GUI框架
pyqt5-tools——pyqt designer设计图形化界面
pyinstaller——最后生成exe文件
二、实现逻辑
懒的画框图了,就简单写一下这两天半的时间分别实现了哪些功能
访问的网页:https://zfw.xidian.edu.cn
对,这是西电的查流量网站,通过F12查看发送接收的数据,可以看到表单里面学号、密码都是明文传输的,这个网站用了有五六年了,不知道***哪里来的自信,一直都没有更新,所以很适合用来python模拟登录练练手
第一步:构建所需的data表单
表单主要分为五部分
data = { '_csrf':'', #这个不知道是干嘛,但从html里面可以找到,所以推测类似流水号一样的东西
'LoginForm[username]':'', #学号
'LoginForm[password]':'', #密码
'LoginForm[verifyCode]':'', #验证码
'login-button':'' #为空值,只是代表了点击过登录按钮
}
第二步:准备百度云的接口
百度云注册账号,创建一个服务,就可以获取APP_ID, API_KEY, SECRET_KEY三个值
APP_ID = '**'
API_KEY = '*****'
SECRET_KEY = '*************'
client = AipOcr(APP_ID, API_KEY, SECRET_KEY) #生成一个实例,后面直接传验证码图片信息
第三步:获取csrf口令及验证码
个人猜测csrf只是一个服务器发来的流水号,类似银行排到的号一样
可能和验证码的值绑定在一起
s = requests.session() #创建会话
res = s.get(url=url,headers=headers) #打开查流量的网站
soup = BeautifulSoup(res.text,"html.parser") #将返回的信息给BeautifulSoup处理
data['_csrf'] = soup.find(attrs ={"name":"csrf-token"}).attrs['content'] #获取csrf的口令
i = soup.find('img',attrs ={"id":"loginform-verifycode-image"}) #获取验证码的地址
再次感谢百度baba提供的这么强大的api接口,很详细的使用说明并且还免费使用,实在是强!
使用方法:
""" 读取图片(注意要以二进制的形式打开图片) """
def get_file_content(filePath):
with open(filePath, 'rb') as fp:
return fp.read()
image = get_file_content('example.jpg')
""" 调用通用文字识别, 图片参数为本地图片 """
client.basicGeneral(image) #这里的client为前面实例化的
返回值:
{
"log_id": 2471272194,
"words_result_num": 2,
"words_result":
[
{"words": " TSINGTAO"},
{"words": "青島睥酒"}
]
}
上面放的代码是官方文档里面的,实际返回验证码的时候,只有对验证码识别的一个值,下面是我的代码
code = client.basicAccurate(image) #发送图片
code1 = code['words_result'][0]['words'] #对返回值进行提取
因为有时候识别的字符串少于4位,肯定是不正确的,因为懒的再更新一遍验证码,所以干脆把原来的验证码重新提交给百度云再识别一遍。。。
最后吧code1的值给到data表单里的verifyCode就可以了
第四步:提交表单,获取网页
剩下的内容在逻辑实现上就很简单了,只是带着数据,在原来的会话里面post一下
取返回值给BeautifulSoup处理一下
放出代码:
def getwebip():
resp=s.post(url='https://zfw.xidian.edu.cn/',data=data)
soup1 = BeautifulSoup(resp.content,"html.parser")
for i in soup1.find('td'):
print(i)
return i
(其实看得出来,我写的很笨。。我自己都这么觉得)
第五步:绘制UI
第一次上手pyqt5,完全不知道怎么操作,我至少需要两个输入栏,一个回显窗口,一个登陆按钮
对应的放置两个lineEdit,一个textBrowser,两个pushButton
界面如图

别的地方基本都没有改动,只是为了实现功能,懒的也是没谁了。。。
第六步:绑定功能
复制别人示例代码,进行魔改,简单~(其实是我真的学不进去了,不想看qt5的教程了T0T)
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QPlainTextEdit,QMessageBox
#PyQt5中使用的基本控件都在PyQt5.QtWidgets模块中
#导入designer工具生成的login模块
from Ui_net import Ui_MainWindow
import net_login
class MyMainForm(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MyMainForm, self).__init__(parent)
self.setupUi(self)
#添加登录按钮信号和槽。注意display函数不加小括号()
self.pushButton.clicked.connect(self.display)
#添加退出按钮信号和槽。调用close函数
self.pushButton_2.clicked.connect(self.close)
def display(self):
#利用line Edit控件对象text()函数获取界面输入
net_login.data['LoginForm[username]'] = self.lineEdit.text()
net_login.data['LoginForm[password]'] = self.lineEdit_2.text()
#利用text Browser控件对象setText()函数设置界面显示
net_login.login()
ip = net_login.getwebip()
self.textBrowser.setText("ip查询结果: "+ ip )
if __name__ == "__main__":
#固定的,PyQt5程序都需要QApplication对象。sys.argv是命令行参数列表,确保程序可以双击运行
app = QApplication(sys.argv)
#初始化
myWin = MyMainForm()
#将窗口控件显示在屏幕上
myWin.show()
#程序运行,sys.exit方法确保程序完整退出。
sys.exit(app.exec_())
第七步:生成exe
其实到第六步已经可以比较完美的实现了我想要的功能,但最终还想尝试一下打包exe
于是我的第一个exe程序诞生了,虽然伴随着很多bug,稍微有点不开心就卡死
但功能还是有的,先放成功的截图

首先安装pip install pyinstaller
PyInstaller 其实就是把 python 解析器和你自己的脚本打包成一个可执行的文件,和编译成真正的机器码完全是两回事,所以千万不要指望成打包成一个可执行文件会提高运行效率,相反可能会降低运行效率,好处就是在运行者的机器上不用安装 python 和你的脚本依赖的库。在 Linux 操作系统下,它主要用的 binutil 工具包里面的 ldd 和 objdump 命令。
其次把用到的py文件放一起,在cmd里面打开这个文件夹
执行pyinstaller -F ***.py
-F 表示生成单个可执行文件
-w 表示去掉控制台窗口,这在GUI界面时非常有用。不过如果是命令行程序的话那就把这个选项删除吧!
-p 表示你自己自定义需要加载的类路径,一般情况下用不到
-i 表示可执行文件的图标
在打包的时候,中途因为路径存在乱码不得已需要加上-p 重新指定路径
于是正常生成了exe文件
完结!撒花!