Javascript Qt5和QML:如何使用WebEngine Quick Nano浏览器自动输入用户名和密码

Javascript Qt5和QML:如何使用WebEngine Quick Nano浏览器自动输入用户名和密码,javascript,qt,qml,qt5,qwebengineview,Javascript,Qt,Qml,Qt5,Qwebengineview,我正在使用Qt和QML编写一个小应用程序,它使用了Qt文档中的示例 在这个例子中,我试图访问我的电子邮件。我可以做到,但我正在尝试自动输入用户名和密码,以便我可以立即登录到我的电子邮件 基本上作为一个例子,启动应用程序后(我的电子邮件地址是硬编码的),我可以看到gmail的username页面,但这里我必须键入我的用户名才能访问下一个有密码的页面: 在这里,我必须键入我的密码: 只有这样,我才能访问我的电子邮件 预期的结果是,只要我运行应用程序,我想直接进入我的电子邮件,而无需输入用户名和密

我正在使用
Qt
QML
编写一个小应用程序,它使用了Qt文档中的示例

在这个例子中,我试图访问我的电子邮件。我可以做到,但我正在尝试自动输入用户名和密码,以便我可以立即登录到我的电子邮件

基本上作为一个例子,启动应用程序后(我的电子邮件地址是硬编码的),我可以看到
gmail
username
页面,但这里我必须键入我的用户名才能访问下一个有
密码的页面:

在这里,我必须键入我的
密码

只有这样,我才能访问我的电子邮件

预期的结果是,只要我运行应用程序,我想直接进入我的电子邮件,而无需输入
用户名
密码

我正在运行的代码如下所示:

#include <QtGui/QGuiApplication>
typedef QGuiApplication Application;
#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlContext>
#include <QtWebEngine/qtwebengineglobal.h>

static QUrl startupUrl()
{
    QUrl ret;
    QStringList args(qApp->arguments());
    args.takeFirst();
    for (const QString &arg : qAsConst(args)) {
        if (arg.startsWith(QLatin1Char('-')))
             continue;
        ret = Utils::fromUserInput(arg);
        if (ret.isValid())
            return ret;
    }

    // first email
    return QUrl(QStringLiteral("https://accounts.google.com/signin"));
}

int main(int argc, char **argv)
{
    QCoreApplication::setOrganizationName("QtExamples");
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    Application app(argc, argv);

    QtWebEngine::initialize();

    QQmlApplicationEngine appEngine;
    Utils utils;
    appEngine.rootContext()->setContextProperty("utils", &utils);
    appEngine.load(QUrl("qrc:/ApplicationRoot.qml"));
    QMetaObject::invokeMethod(appEngine.rootObjects().first(), "load", Q_ARG(QVariant, startupUrl()));

    return app.exec();
}
#包括
typedef-qgui应用程序;
#包括
#包括
#包括
静态QUrl startupUrl()
{
QUrl-ret;
QStringList参数(qApp->arguments());
args.takeFirst();
用于(常量字符串和参数:qAsConst(参数)){
if(参数startsWith(QLatin1Char('-'))
继续;
ret=Utils::fromUserInput(arg);
if(ret.isValid())
返回ret;
}
//第一封电子邮件
返回QUrl(QStringLiteral(“https://accounts.google.com/signin"));
}
int main(int argc,字符**argv)
{
QCoreApplication::setOrganizationName(“QtExamples”);
QCoreApplication::setAttribute(Qt::AA_enableHighdDiscaling);
应用程序应用程序(argc、argv);
QtWebEngine::initialize();
qqmlaplicationengine;
Utils-Utils;
rootContext()->setContextProperty(“utils”和&utils);
appEngine.load(QUrl(“qrc:/ApplicationRoot.qml”);
QMetaObject::invokeMethod(appEngine.rootObjects().first(),“load”,Q_ARG(QVariant,startupUrl());
返回app.exec();
}
我到目前为止所做的尝试

  • 我已经做了很多研究,并且在试图理解如何硬编码条目的概念时很有用。但是,如何进入下一个
    passowrd
    page`

  • 是另一个使用不同方法解决相同问题的示例(尽管在
    php
    )。这也有助于理解概念和主要思想

  • 看起来是一个很好的例子,尽管这里使用了
    JavaScript

  • 现在在阅读了更多的信息后,我发现最好的方法是在
    QML
    代码中集成一些
    JavaScript
    ?我是
    JavaScript
    的新手,如果这是正确的路线的话。如果这是正确的事情,我该怎么做

    我正在考虑在这个应用程序中使用,但我不确定如何最好地实现它

    感谢所有可能已经经历过这一过程的人,感谢他们为如何在
    WebEngine Quick Nano Browser
    中实现这一点提供了一些指导或示例。

    不要使用示例WebEngine Quick Nano Browser,因为我认为它不必要,只会分散背景目标的注意力

    逻辑是要理解google登录是如何工作的,在这种情况下,您必须找到一种使用javascript获取DOM元素的方法,例如通过id、类、名称等,并根据所需的逻辑对其进行修改。还要注意,url会发生变化,因此在每个url中必须执行不同的脚本

    考虑到上述情况,解决方案是:

    import QtQuick 2.13
    import QtQuick.Controls 2.13
    import QtWebEngine 1.9
    
    ApplicationWindow{
        id: root
        width: 640
        height: 480
        visible: true
    
        property string username: "USERNAME"
        property string password: "PASSWORD"
    
        QtObject{
            id: internals
            property string script_username: "
                setTimeout(function() {
                    var input_username = document.getElementById('identifierId');
                    input_username.value = '%1';
                    var button = document.getElementById('identifierNext');
                    button.click();
                }, 1000);
            ".arg(username)
    
            property string script_password: "
                setTimeout(function() { 
                    var input_password = document.getElementsByName('password')[0];
                    input_password.value = '%1';
                    var button = document.getElementById('passwordNext');
                    button.click();
                }, 1000);
            ".arg(password)
        }
    
        WebEngineView {
            id: view
            anchors.fill: parent
            onUrlChanged: {
                if(url == "https://accounts.google.com/signin/v2/identifier?flowName=GlifWebSignIn&flowEntry=ServiceLogin"){
                    view.runJavaScript(internals.script_username)   
                }
                else if(url == "https://accounts.google.com/signin/v2/sl/pwd?flowName=GlifWebSignIn&flowEntry=ServiceLogin&cid=1&navigationDirection=forward"){
                    view.runJavaScript(internals.script_password)
                }
            }
            Component.onCompleted: view.url = "https://accounts.google.com/signin"
        }
    }
    

    谢谢你,这正是我要找的例子。是的,我现在正在研究DOM的元素是如何工作的。再次感谢!:)