python制作网易账号余额查询工具

来源:互联网 发布:淘宝的昵称有什么用 编辑:程序博客网 时间:2024/06/10 21:05

制作一个自动登录,手动滑动验证码,自动读取余额的工具,完成后再做验证码识别的部分。
先展示一下完成的结果。
结果展示
github地址:https://github.com/TechKuki/NeteastBalance

实现自动登录

python自带的tkinter框架没有能够支持展示网页的控件,查询到python开发gui程序还可以使用wxPython,PyQt,PySide等。
这里我们使用PyQt5,使用 pip3 install PyQt5 安装。安装完成后PyQt5的版本是5.9。
正常思路是寻找登录的接口,然后post数据上去,但是找了好久只找到要post的地址,没找到怎么生成post数据。这里如果有大佬研究过了请指教一下。
换一种思路,操作js代码进行登录。
浏览器里打开http://ecard.163.com/index_login?refer_uri=%2Findex,然后F12,进入Console,执行
document.getElementById('dologin').click()
可以看到模拟了登录的点击操作。
然后来找一找PyQt中向页面执行js代码的接口,查询到QWebEngineView的runJavaScript函数可以执行,但是这个函数只能操作打开的页面的dom对象,而登录要操作的文本框、按钮等在一个iframe当中,无论怎么写js代码都操作不到,这里卡住了。继续在api里找,找到QWebEngineScript的setRunsOnSubFrames看起来像是可以在iframe中执行代码,写几行代码实验了下果然可以。
写js的时候又发现,网页中的某些东西是动态加载进来的,我们的js执行的时候有可能网页还没加载完,所以这里用了一个计时器。
关键代码:

# -*- coding: utf-8 -*-import sysfrom PyQt5.QtCore import QUrlfrom PyQt5.QtWidgets import QApplicationfrom PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineScriptapp = QApplication(sys.argv)browser = QWebEngineView()browser.load(QUrl("http://ecard.163.com/account/query_balance"))script = QWebEngineScript()script.setInjectionPoint(QWebEngineScript.Deferred)script.setRunsOnSubFrames(True)script.setSourceCode("""    var box = document.getElementById('cnt-box');    if(box){        function interFunc(){            if(box.children.length == 4 && document.getElementById('nerror').children.length == 2){                clearInterval(interId);                email = document.getElementsByName('email');email[0].value='username@163.com';                password = document.getElementsByName('password');password[0].value='password';                document.getElementById('dologin').click();            }        }        var interId = setInterval(interFunc, 100);    }""")browser.page().scripts().insert(script)browser.show()sys.exit(app.exec_())

实现查询数据

这里同样通过执行js的方式实现,在浏览器的开发者工具中找到需要提取的部分,然后使用QWebEnginePage的loadFinished信号。
关键代码:

def js_callback(balance):    print(balance)def load_finished(isOk):    if isOk:        if page.requestedUrl() == QUrl("http://ecard.163.com/handle_query_verify"):        page.runJavaScript("document.getElementsByClassName('red bold')[2].innerText", js_callback)    else:        print("load error")page.loadFinished.connect(load_finished)

实现连续查询

因为有多个账号需要查询余额,所以我们要实现在查询完一个账号后继续查询下个账号。这一步我将代码封装成了一个类,连续查询的逻辑没什么好讲的,直接上代码。

class Balance(QWebEngineView):    def __init__(self, accounts):        #...    def loadFinished(self, isOk):        #...    def jsCallback(self, balance):        self.index = self.index + 1        print(balance)        self.startQuery()    def startQuery(self):        if self.index < len(self.accounts):            self.load(self.urlLogin)if __name__ == "__main__":    accounts = [('user1@163.com', 'password'),        ('user2@163.com', 'password'),        ('user3@163.com', 'password')]    app = QApplication(sys.argv)    balanceView = Balance(accounts)    balanceView.startQuery()    balanceView.show()    sys.exit(app.exec_())

调整验证码显示

到上一步已经实现了查询工具的主要逻辑,但是因为我们是直接将网页加载进来,页面上有很多多余的内容十分碍眼,而且登录界面的验证码和查询界面的验证码不在一个位置,每次查询需要拖动view的滚动条且鼠标移动的距离非常远,导致使用体验非常差。
这一步我们把页面上多余的内容全部删除或者隐藏,调整验证码显示的位置,做到页面上只显示关键部分。
在chrome的开发者工具上逐个元素的删除调整,将有调整的元素都记录下来,这里需要有一丢丢的css知识。最后关键代码如下。

def loadFinished(self, isOk):    if isOk:        requestedUrl = self.page().requestedUrl()        if requestedUrl == self.urlLogin:            self.page().runJavaScript("""                //#footer,#header,#urs_tab,#phone_tab删掉                $('#footer').remove()                $('#header').remove()                $('#urs_tab').remove()                $('#phone_tab').remove()                //.nowbg的class属性删掉                $('.nowbg').removeAttr('class')                //#wrap的min-width属性去掉                $('#wrap').css('min-width', 'initial');                //#center的width属性去掉                $('#center').css('width', 'initial');                //#login的border-top,height,position,right,top属性去掉,加margin:auto;                $('#login').css('border-top', 'initial');                $('#login').css('height', 'initial');                $('#login').css('position', 'initial');                $('#login').css('right', 'initial');                $('#login').css('top', 'initial');                $('#login').css('margin', 'auto');            """)        elif requestedUrl == self.urlVerify:            self.page().runJavaScript("""                //#footer,#header,.situation删掉                $('#footer').remove()                $('#header').remove()                $('.situation').remove()                //#wrap的min-width属性去掉                $('#wrap').css('min-width', 'initial');                //#main的width属性去掉                $('#main').css('width', 'initial');                //.mb-content的margin: 100px auto 78px auto;                $('.mb-content').css('margin', '100px auto 78px auto')            """)        elif requestedUrl == self.urlBalance:            self.page().runJavaScript("document.getElementsByClassName('red bold')[2].innerText", self.jsCallback)    else:        print("load error")if __name__ == "__main__":    #...    balanceView.resize(360, 363)    #...

到这里工具已经基本可用了,调整完后使用的界面如下:
这里写图片描述

验证码拖动后自动点击确定

每次拖完验证码后还需要再点一下按钮,这个点按钮的工作也可以让js来做。验证码验证成功后右边会出现一个绿色的对勾,通过检查这个对勾是否存在来确定点击按钮的时机。关键代码如下。

//登录界面function verifyFunc(){    if(document.getElementsByClassName('u-suc').length == 2){        clearInterval(verifyId);        document.getElementById('dologin').click();    }}var verifyId = setInterval(verifyFunc, 100);//查询界面function verifyFunc(){    if($('.TxtStatus').children().length == 1){        clearInterval(verifyId);        $('#query_verify_form').submit();    }}var verifyId = setInterval(verifyFunc, 100);

查询结果展示到窗体上

查询结果目前都是直接打印到控制台里,查看起来十分不方便,这一步我们把查询结果显示在一个表格上。并且整理了下界面的显示。
表格代码:

# -*- coding: utf-8 -*-from PyQt5.QtWidgets import QTableWidget, QTableWidgetItem, QAbstractItemView, QHeaderViewclass BalanceTable(QTableWidget):    def __init__(self):        QTableWidget.__init__(self)        self.setEditTriggers(QAbstractItemView.NoEditTriggers)        self.setColumnCount(2)        self.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)        self.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeToContents)        self.setHorizontalHeaderLabels(["账号", "余额"])    def addItem(self, account, balance):        rowCount = self.rowCount()        self.insertRow(rowCount)        self.setItem(rowCount, 0, QTableWidgetItem(account))        self.setItem(rowCount, 1, QTableWidgetItem(balance))

之前的回调函数处理成调用BalanceTable的addItem函数。

class BalanceView(QWebEngineView):    #...    def jsCallback(self, balance):        if self.queryCallBack:            self.queryCallBack(self.accounts[self.index][0], balance)        self.index = self.index + 1        self.startQuery()    #...    def startQuery(self, queryCallBack=None):        if queryCallBack:            self.queryCallBack = queryCallBack        #...class Neteast(QWidget):    def startQuery(self):        if self.accounts:            self.balanceView.startQuery(self.queryCallBack)    def queryCallBack(self, account, balance):        self.balanceTable.addItem(account, balance)

增加查询进度条

进度条的使用比较简单,我们要用到的只有2个函数。

progressBar = QProgressBar()progressBar.setTextVisible(False)progressBar.setValue(val)vboxLayout.addWidget(progressBar)

账号密码提出到单独文件

账号和密码直接写到代码里看起来总有那么一点不舒服,最后一步我们把账号单独放在一个文件里。

#neteast.pyif __name__ == "__main__":    from account import accounts    #...#account.pyaccounts = [('user1@163.com', 'password'),    ('user2@163.com', 'password'),    ('user3@163.com', 'password')]

最后完成的代码可以在github上查看。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 做事不专心老走神怎么办 小朋友做作业老发呆走神怎么办? 小朋友总是上课走神发呆怎么办 21岁精神心急了怎么办 一直有人阻止我做事怎么办 安装了渲染su找不到怎么办 su室内渲染很暗怎么办 su未响应未保存怎么办 电脑工作栏没了怎么办 ps工作栏没了怎么办 草图大师文件太大打不开怎么办 su模型保存后不见了怎么办 墨汁溅到衣服上怎么办 黑裤子溅上白色颜料怎么办 解码器上墙后图像放大了怎么办 宝宝把墙画了怎么办 孩子画画勾线笔过敏怎么办 微信语音撤回了怎么办? 小天才电话手表充不上电怎么办 儿童电话手表定位不准怎么办 2岁宝宝不让刷牙怎么办 宝宝两岁蛀牙多还不刷牙怎么办 宝宝有蛀牙不肯刷牙怎么办 宝宝牙疼怎么办4岁 3岁宝宝龋齿牙疼怎么办 2岁宝宝不肯刷牙怎么办 3岁宝宝不爱刷牙怎么办 2岁宝宝不刷牙怎么办 二岁宝宝牙不好怎么办 小孩一刷牙就吐怎么办 孩子一刷牙就吐怎么办 两岁宝宝闹人怎么办 3岁宝宝不愿意刷牙怎么办 孩子牙没掉长出新牙来了怎么办 大孩子不洗澡怎么办啊 2岁宝宝不爱洗澡怎么办 手指画颜料变干怎么办 刮画纸画错了怎么办 电脑绘的图不能扩大怎么办 华腾同步课堂忘记密码怎么办 被缝纫机针扎了怎么办