说点废话:
之前一直想做一个校园网用路由器的便捷工具,一开始想过用爬虫实现,但奈何网络方面知识较为薄弱,爬取不到信息,甚至连绕过登录都没实现,带cookie获取一直获取不来,貌似是腾达用的sesion来传递数据的?不清楚。。所以饶了一大圈,决定使用模拟网页点击事件来获取登录完的路由器页面的信息
进入正题
Qt 5.10的浏览器控件是QWebEngine,5.6之前版本是QWebKit
此处使用的是QWebEngine的控件,所以需要在工程文件中添加
QT += webenginewidgets
模拟网页点击,需要用到以下两个类
QWebEngineView
QWebEnginePage
首先是在view中加载你要访问的地址,然后使用一个page指针指向view当前的page对象
通过page对象调用函数 运行js代码来达到点击页面的效果
代码段
QWebEngineView * m_brower;
QWebEnginePage * m_page;
m_brower = new QWebEngineView(this);
m_brower->load(QUrl("http://192.168.1.1"));
m_page = m_brower->page();
m_page->runJavaScript(js);
m_page->runJavaScript(js, [=](const QVarinat& v){
});
runJavaScript这个函数,上面第一个是只运行js代码
第二个是运行js代码并获取运行之后的值
例如
//runJavaScript函数可以获取到js运行的结果,可使用 Lambda 表达式,参数为const QVariant&
//获取一个页面元素的属性值
QString js = "document.getElementById(\"login-password\").getAttribute(\"type\")";
m_page->runJavaScript(js, [=](const QVarinat& v){
qDebug() << v.toString();
});
建议是加上 Lambda表达式 ,就算不需要取值,也可以发出运行完js代码的信号(自定义一个信号),这里好像是异步的,所以需要通过信号槽来判断是否运行完毕。
一个小demo
通过点击pushbutton来模拟页面点击登录,只是点击了button就完成了登录操作,进入路由器主页
代码
头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWebEngineView>
#include <QWebEnginePage>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void jsFinished();
private slots:
void onLoginbtnClicked();
private:
Ui::MainWindow *ui;
QWebEngineView * m_brower;
QWebEnginePage * m_page;
int m_finished = 0;
};
#endif // MAINWINDOW_H
cpp文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_brower = new QWebEngineView(this);
m_brower->load(QUrl("http://192.168.1.1"));
m_page = m_brower->page();
ui->verticalLayout->addWidget(m_brower);
connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::onLoginbtnClicked);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onLoginbtnClicked()
{
//密码为路由器密码,此处就不写出来了
QString password = "********";
//此处为寻找页面属性中ID为login-password的输入框,填写它的值
QString setPasswordJs = tr("document.getElementById(\"login-password\").value=\"%1\"").arg(password);
//此处为寻找页面属性中ID为save的按钮,触发点击事件
QString clickedJs = "document.getElementById(\"save\").click()";
//在跑js代码的过程中最好要发出完成的信号,以防止出现bug
//可以不写Lambda 表达式,直接跑js代码,此处是为了防止bug
m_page->runJavaScript(setPasswordJs, [=](const QVariant&){
emit jsFinished();
qDebug() << "1";
});
m_page->runJavaScript(clickedJs, [=](const QVariant&){
emit jsFinished();
qDebug() << "2";
});
//runJavaScript函数可以获取到js运行的结果,可使用 Lambda 表达式,参数为const QVariant&
/*
//获取一个页面元素的属性值
QString js = "document.getElementById(\"login-password\").getAttribute(\"type\")";
m_page->runJavaScript(js, [=](const QVarinat& v){
qDebug() << v.toString();
});
*/
connect(this, &MainWindow::jsFinished, [=](){
++m_finished;
if(m_finished == 2){
this->setWindowTitle("load finished");
m_finished = 0;
}
});
}