qml,python,selenium相结合,可视化爬虫实践。

    python 是门好语言,简单上手,轮子多。qml 是一个非常好的桌面工具,像html 一样的语法开发迅速,界面好看。selenium 是自动化测试与爬虫非常好的工具。

   使用python,qml,selenium结合,可以开发出可视化的爬虫。

  qml 做前端与python 通信,python再调用selenium 爬取数据,将过程,结果不断反馈给qml 进行显示。

   第一步: 新建main.qml 文件做出主界面。

import QtQuick 2.15
import QtQuick.Window
import QtQuick.Controls
Window {
    id: root
    width: 1050
    height: 600
    visible: true
    title: qsTr("python-qml")

}

第二步:使用python 运行qml,我这里使用的 pyside6 。

# coding=utf-8
from PySide6.QtWidgets import QApplication
from PySide6.QtGui import QIcon
from PySide6.QtQml import QQmlApplicationEngine
import sys

if __name__ == "__main__":
    app = QApplication(sys.argv)
    engine = QQmlApplicationEngine()
    engine.load("main.qml")
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec())

这样第一个qml 应用就开始了。

接下来需要python与qml 可以相互通信才能互相传递数据。

qml 去调用python是需要桥的。

# coding=utf-8
from PySide6.QtCore import QObject, Slot
from PySide6.QtWidgets import QApplication
from PySide6.QtGui import QIcon
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtQml import QmlElement
import sys
QML_IMPORT_NAME = "io.qt.textproperties"
QML_IMPORT_MAJOR_VERSION = 1

@QmlElement
class Bridge(QObject):

    @Slot(int, result=int)
    def getdata(self, num):
        return num*num


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon('icon/box2-heart-fill.svg'))
    engine = QQmlApplicationEngine()
    bridge = Bridge()
    engine.rootContext().setContextProperty('bridge', bridge)
    engine.load("main.qml")
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec())

   我们需要在python中定义这个一个继承QObect的类,并注册到qml当中。这样qml 就能调用到python 类中定义的方法。其中 @Slot 约定了双方发送参数的格式与接受参数的格式。

QML_IMPORT_NAME = "io.qt.textproperties"
QML_IMPORT_MAJOR_VERSION = 1

这两句话不能少,具体作用可以查看Qt 的官方手册。

  qml 是用  js 作为脚本语言,调用python 如下。

import QtQuick 2.15
import QtQuick.Window
import QtQuick.Controls
Window {
    id: root
    width: 1050
    height: 600
    visible: true
    title: qsTr("python-qml")
    Component.onCompleted: {
        let b = bridge.getdata(10)
        print(b)
    }
}

我们可以在窗口看到qml 的输出

这样qml调用python 就完成了。

而python主动给qml 发消息需要qt 里面的信号 Signal。信号同样需要定义在桥里面。

from PySide6.QtCore import Signal #注意导入信号
@QmlElement
class Bridge(QObject):
    sig = Signal(str, arguments=['res'])
    @Slot(int, result=int)
    def getdata(self, num):
        return num*num

 Signal 第一个参数代表参数的类型,第二个参数代表qml接受的参数名称。qml 要接收到此信号发的消息就要监听此信号。

import QtQuick 2.15
import QtQuick.Window
import QtQuick.Controls
Window {
    id: root
    width: 1050
    height: 600
    visible: true
    title: qsTr("python-qml")
    Component.onCompleted: {
        let b = bridge.getdata(10)
        print(b)
    }
    Connections{
        target: bridge
        function onSig(res){
           print(res)
        }
    }
}
# coding=utf-8
import time

from PySide6.QtCore import QObject, Slot, Signal
from PySide6.QtWidgets import QApplication
from PySide6.QtGui import QIcon
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtQml import QmlElement
import sys
import threading
QML_IMPORT_NAME = "io.qt.textproperties"
QML_IMPORT_MAJOR_VERSION = 1

@QmlElement
class Bridge(QObject):
    sig = Signal(str, arguments=['res'])
    @Slot(int, result=int)
    def getdata(self, num):
        return num*num

def timetoprint(bridge):
    while 1:
        bridge.sig.emit("hello!!!")
        time.sleep(1)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon('icon/box2-heart-fill.svg'))
    engine = QQmlApplicationEngine()
    bridge = Bridge()
    engine.rootContext().setContextProperty('bridge', bridge)
    engine.load("main.qml")
    t = threading.Thread(target=timetoprint,args=(bridge,))
    t.start()
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec())

 qml 就能收到我们主动发的消息了。在有了前面的前置条件后,就能往下不断的开发功能,开发界面了。

  接下来是selenium,不用过多介绍,网上有许多的资料,选用selenium 是因为现在的网站资源大多是动态加载的,无法通过静态网页来获取,requests有点力不从心。selenium 能够很好的模拟浏览器,达到欺骗网站的效果。这次的实践网站,就以全球拥有巨大访问量的P站做练习。P站的视频时使用m3u8做索引的流式视频,但主要的m3u8 链接是由js动态生成的,并且js代码还被混淆。

道高一尺,魔高一丈,我们使用selenium-wire 直接抓取网站发出m3u8 链接,抓到链接后再解析其中的ts 链接并下载合成。

主要思路为qml 输入链接-> python 收到链接 开多线程启动selenium 打开链接 -> selenium加载网页完毕->selenium-wire 获取请求链接-> 匹配其中的m3u8 链接 解析下载 -> ffmpeg 合成。

 

哈哈,终于可以在P站愉快的学习微积分而不用被妈妈发现了 >_< 。

对项目感兴趣的小伙伴可以去GitHub 上瞧瞧  github.com/alishanjack/h-box 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值