www.91084.com

GVKun编程网logo

从 QWebEngineView 自动登录到网站(qt打开网页 自动登录)

12

这篇文章主要围绕从QWebEngineView自动登录到网站和qt打开网页自动登录展开,旨在为您提供一份详细的参考资料。我们将全面介绍从QWebEngineView自动登录到网站的优缺点,解答qt打开

这篇文章主要围绕从 QWebEngineView 自动登录到网站qt打开网页 自动登录展开,旨在为您提供一份详细的参考资料。我们将全面介绍从 QWebEngineView 自动登录到网站的优缺点,解答qt打开网页 自动登录的相关问题,同时也会为您带来asp.net – RazorViewEngine.FindView无法找到预编译的视图、asp.net-mvc – 单元测试ViewEngines.Engines.FindView的正确方法是什么?、c – QWebEnginePage中的透明背景、c – QWebEngineView在外部浏览器中打开的实用方法。

本文目录一览:

从 QWebEngineView 自动登录到网站(qt打开网页 自动登录)

从 QWebEngineView 自动登录到网站(qt打开网页 自动登录)

如何解决从 QWebEngineView 自动登录到网站?

我正在尝试使用下面的代码在 pyside2 应用程序中创建 monday.com 的视图。我希望能够直接从代码登录,而不必输入我的电子邮件和密码。我发现了一些与下面显示的代码非常相似的代码,并将其调整为 monday.com 登录页面的结构。

我目前可以输入我的电子邮件和密码以及单击登录按钮。但是,出于某种原因,尽管您可以直观地看到这些条目,但该页面似乎没有检测到这些条目。

我尝试放置在“handle_load_finished”之后运行的第二个函数,并包含用于单击此处按钮的 JavaScript,但它仍会运行并且未检测到条目是否存在。

from pyside2.QtCore import QUrl
from pyside2.QtWidgets import QMainWindow,QApplication
from pyside2.QtWebEngineWidgets import QWebEngineView

import os
import sys


class MainWindow(QMainWindow):
    def __init__(self,*args,**kwargs):
        super(MainWindow,self).__init__(*args,**kwargs)

        self.browser = QWebEngineView()
        self.browser.setUrl(QUrl("https://miu2021.monday.com/auth/login_monday/email_password"))
        self.setCentralWidget(self.browser)

        self.browser.loadFinished.connect(self.handle_load_finished)

    def handle_load_finished(self,ok):
        if ok:
            print("Page loaded successfully")
            self.browser.page().runJavaScript("let ap = document.querySelector(''#user_email'');"
                                              "ap.value = ''email@email.com'';"
                                              "let pa = document.querySelector(''#user_password'');"
                                              "pa.value = ''password'';"
                                              "let btn = document.getElementsByTagName(''button'')[0];"
                                              "btn.click();")
        else:
            print("Could not load page")


app = QApplication(sys.argv)
window = MainWindow()
window.show()

app.exec_()

应用图片:

App Image

解决方法

该网站似乎检测到触摸以验证用户是否键入,而不是自动任务。一个可能的解决方案是通过发送 QKeyEvents 来使 Qt 写入,如下所示。

import sys

from PySide2.QtCore import QCoreApplication,QEvent,Qt,QTimer,QUrl
from PySide2.QtGui import QKeyEvent
from PySide2.QtWidgets import QApplication,QMainWindow
from PySide2.QtWebEngineWidgets import QWebEngineView

KEYMAP = {
    "a": Qt.Key_A,"b": Qt.Key_B,"c": Qt.Key_C,"d": Qt.Key_D,"e": Qt.Key_E,"f": Qt.Key_F,"g": Qt.Key_G,"h": Qt.Key_H,"i": Qt.Key_I,"j": Qt.Key_J,"k": Qt.Key_K,"l": Qt.Key_L,"m": Qt.Key_M,"n": Qt.Key_N,"o": Qt.Key_O,"p": Qt.Key_P,"q": Qt.Key_Q,"r": Qt.Key_R,"s": Qt.Key_S,"t": Qt.Key_T,"u": Qt.Key_U,"v": Qt.Key_V,"w": Qt.Key_W,"x": Qt.Key_X,"y": Qt.Key_Y,"z": Qt.Key_Z,"1": Qt.Key_1,"2": Qt.Key_2,"3": Qt.Key_3,"4": Qt.Key_4,"5": Qt.Key_5,"6": Qt.Key_6,"7": Qt.Key_7,"8": Qt.Key_8,"9": Qt.Key_9,"0": Qt.Key_0,".": Qt.Key_Period,"''": Qt.Key_Apostrophe,}


def write_text(widget,text):
    for letter in text:
        key = KEYMAP.get(letter.lower(),Qt.Key_unknown)
        event = QKeyEvent(QEvent.KeyPress,key,Qt.NoModifier,letter)
        QCoreApplication.postEvent(widget.focusProxy(),event)


class MainWindow(QMainWindow):
    def __init__(self,*args,**kwargs):
        super(MainWindow,self).__init__(*args,**kwargs)

        self.browser = QWebEngineView()
        self.browser.load(
            QUrl("https://miu2021.monday.com/auth/login_monday/email_password")
        )
        self.setCentralWidget(self.browser)

        self.browser.loadFinished.connect(self.handle_load_finished)

    def handle_load_finished(self,ok):
        if ok:
            QTimer.singleShot(100,self.write_email)
        else:
            print("Could not load page")

    def write_email(self,*args):
        self.browser.page().runJavaScript(
            """let ap = document.querySelector(''#user_email'')
                ap.focus();""",self.callback_email,)

    def callback_email(self,*args):
        write_text(self.browser,"email@email.com")
        QTimer.singleShot(100,self.write_password)

    def write_password(self):
        self.browser.page().runJavaScript(
            """let pa = document.querySelector(''#user_password'');
                pa.focus();""",self.callback_password,)

    def callback_password(self,"password")
        QTimer.singleShot(100,self.click)

    def click(self):
        self.browser.page().runJavaScript(
            """let btn = document.getElementsByTagName(''button'')[0];
                btn.focus();
                btn.click();"""
        )


def main():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

asp.net – RazorViewEngine.FindView无法找到预编译的视图

asp.net – RazorViewEngine.FindView无法找到预编译的视图

App.Web和App.Views是我在一个解决方案中的项目,我将我的视图放在App.Views中并使用 RazorGenerator预编译.如果我使用App.Web之类的话,它运行良好,

~/Views/Index.cshtml is virtual path of my view in App.View

它可以在App.Web中成功呈现此视图

public ActionResult Index() {
  return View("~/Views/Index.cshtml");
}

但是当我尝试RenderViewToString时,它返回null.

class FakeController : ControllerBase
{
    protected override void ExecuteCore() { }
    public static string RenderViewToString(string controllerName,string viewName,object viewData)
    {
        using (var writer = new StringWriter())
        {
            var routeData = new RouteData();
            routeData.Values.Add("controller",controllerName);
            var fakeControllerContext = new ControllerContext(new HttpContextwrapper(new HttpContext(new HttpRequest(null,"http://google.com",null),new HttpResponse(null))),routeData,new FakeController());
            var razorViewEngine = new RazorViewEngine();
            var razorViewResult = razorViewEngine.FindView(fakeControllerContext,viewName,"",false);
            var viewContext = new ViewContext(fakeControllerContext,razorViewResult.View,new ViewDataDictionary(viewData),new TempDataDictionary(),writer);
            razorViewResult.View.Render(viewContext,writer);
            return writer.ToString();
        }
    }
}

这就是它的全部,

FakeController.RenderViewToString("FakeName","~/Views/Index.csthml",MessageModel);

enter image description here

This is discussed and probably solved in asp.net core,但我正在使用asp.net mvc 5.

你能不能帮我弄清楚,为什么它不起作用?

解决方法

您正在尝试使用Razor View Engine获取预编译的视图.这是个错误. Razor引擎根据cshtml文件生成视图.但是,在预编译视图的情况下,razorGenerator已经将cshtml文件编译为从System.Web.Mvc.WebViewPage派生的一组类.这些类重写方法Execute()(由RazorGenerator基于输入cshtml自动生成),该方法将html写入输出TextWriter.
原始视图文件(cshtml)不再需要,因此不会与应用程序一起部署.当您调用Razor尝试定位cshtml并基于它构建视图时,它应该返回null视图.

ASP.NET MVC支持多个视图引擎(实现System.Web.Mvc.IViewEngine的类). RazorViewEngine就是其中之一. RazorGenerator.Mvc NuGet包添加了自己的视图引擎(precompiledMvc​​Engine),该引擎基于预编译视图工作.已注册的视图引擎存储在ViewEngines.Engines集合中.当您安装RazorGenerator.Mvc NuGet包时,它会添加注册precompiledMvc​​Engine实例的RazorGeneratorMvcStart类:

[assembly: WebActivatorEx.PostApplicationStartMethod(typeof(App.Views.RazorGeneratorMvcStart),"Start")]

namespace App.Views {
    public static class RazorGeneratorMvcStart {
        public static void Start() {
            var engine = new precompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly) {
                UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal
            };

            ViewEngines.Engines.Insert(0,engine);

            // StartPage lookups are done by WebPages. 
            VirtualPathFactoryManager.RegisterVirtualPathFactory(engine);
        }
    }
}

您应该使用此precompiledMvc​​Engine实例而不是RazorViewEngine来访问预编译视图.以下是RenderViewToString方法的调整代码:

public static string RenderViewToString(string controllerName,object viewData)
{
    using (var writer = new StringWriter())
    {
        var routeData = new RouteData();
        routeData.Values.Add("controller",controllerName);
        var fakeControllerContext = new ControllerContext(new HttpContextwrapper(new HttpContext(new HttpRequest(null,new FakeController());
        var viewEngine = ViewEngines.Engines.OfType<precompiledMvcEngine>().FirstOrDefault();
        if (viewEngine == null)
        {
            throw new InvalidOperationException("precompiledMvcEngine is not registered");
        }
        var viewResult = viewEngine.FindView(fakeControllerContext,false);
        var viewContext = new ViewContext(fakeControllerContext,viewResult.View,writer);
        viewResult.View.Render(viewContext,writer);
        return writer.ToString();
    }
}

一个重要的注意事项:您应该将RazorGenerator.Mvc NuGet包安装到带有视图的项目(App.Views)中,而不是安装到Web应用程序项目中,因为precompiledMvc​​Engine将当前程序集作为预编译视图的源. Aslo确保没有将RazorGeneratorMvcStart添加到App.Web项目中.当我添加了对RazorGenerator.Mvc.dll程序集的引用时,它发生在我身上.

Sample Project on GitHub

asp.net-mvc – 单元测试ViewEngines.Engines.FindView的正确方法是什么?

asp.net-mvc – 单元测试ViewEngines.Engines.FindView的正确方法是什么?

我最近对我的mvc应用程序进行了一些重构,并意识到返回了很多静态视图.而不是让多个控制器具有仅返回视图的操作结果,我决定创建一个控制器,如果它们存在则返回静态视图,如果视图不存在则抛出404错误.

public ActionResult Index(string name)
{
    ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext,name,null);

    if (result.View == null)
        ThrowNotFound("Page does not exists.");

    return View(name);
}

我的问题是单元测试的正确方法是什么?我尝试了下面的代码,但我得到的错误是“RouteData必须包含一个名为’controller’且具有非空字符串值的项”.

[Theory]
[InlineData("ContactUs")]
public void Index_should_return_view_if_view_exists(string name)
{
    controller = new ContentController();
    httpContext = controller.MockHttpContext("/","~/Content/Index","GET"); ;

    var result = (ViewResult)controller.Index(name);

    Assert.NotNull(result.View);
}

我的目的是让单元测试出去并获取真实的视图.然后我开始怀疑是否应该使用SetupGet为FindView模拟ViewEngines并创建两个测试,其中第二个测试如果视图为null则抛出未找到的异常.

测试此功能的正确方法是什么?任何指针,示例代码或博客文章都会有所帮助.

谢谢

解决方法

您应该创建一个模拟的视图引擎并将其放入集合中:

[Theory]
[InlineData("ContactUs")]
public void Index_should_return_view_if_view_exists(string name)
{
    var mockViewEngine = MockRepository.GenerateStub<IViewEngine>();
    // Depending on what result you expect you Could set the searched locations
    // and the view if you want it to be found
    var result = new ViewEngineResult(new [] { "location1","location2" });
    // Stub the FindView method
    mockViewEngine
        .Stub(x => x.FindView(null,null,false))
        .IgnoreArguments()
        .Return(result);
    // Use the mocked view engine instead of WebForms
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(mockViewEngine);

    controller = new ContentController();

    var actual = (ViewResult)controller.Index(name);

    Assert.NotNull(actual.View);
}

c – QWebEnginePage中的透明背景

c – QWebEnginePage中的透明背景

我们正在尝试将一些应用程序从Qt 4移植到Qt 5.4. Qt 5.4有一个新的Web引擎.我们曾经使QWebView和QWebPage的背景透明:
view = new QWebView(this);
QPalette palette = view->palette();
palette.setBrush(QPalette::Base,Qt::transparent);
view->page()->setPalette(palette);
view->setAttribute(Qt::WA_OpaquePaintEvent,false);

但是这段代码不适用于QWebEngineView和QWebEnginePage.关键是QWebEnginePage没有像setPalette这样的API.

谁能找到解决这个问题的方法?

解决方法

如 https://bugreports.qt.io/browse/QTBUG-41960中所述,现在只需使用以下行即可:
webEngineView->page()->setBackgroundColor(Qt::transparent);

我在Qt 5.6中尝试过,它运行良好.

更新:为了使这个答案更有帮助,让我展示所有相关的代码.

在MainWindow中,我设置了这个:

setAttribute(Qt::WA_TranslucentBackground);
setAutoFillBackground(true);
setwindowFlags(Qt::FramelessWindowHint);

对于webEngineView对象,我设置了以下属性:

webEngineView->setAttribute(Qt::WA_TranslucentBackground);
webEngineView->setStyleSheet("background:transparent");
webEnginePage = webEngineView->page();
// https://bugreports.qt.io/browse/QTBUG-41960
webEnginePage->setBackgroundColor(Qt::transparent);

我希望它有所帮助.

c – QWebEngineView在外部浏览器中打开

c – QWebEngineView在外部浏览器中打开

我正在将我的代码从QtWebKit移动到QtWebEngine.总的来说,过渡相当顺利,但是,我坚持一个特定的问题.我使用QWebEngineView显示Google Maps页面.放置的一些标记有信息窗口,弹出“单击此处获取更多信息”,在外部浏览器中打开链接.

使用QtWebKit,通过setLinkDelegation策略可以轻松实现.但是,这里似乎有点复杂.我试图按照这个例子,但不知怎的,我需要在QWebEngineView中重新定义QWebEnginePage.以下是我到目前为止所提出的内容.知道如何实际连接这一切吗?

谢谢

#ifndef MYQWEBENGINEVIEW_H
#define MYQWEBENGINEVIEW_H

#include <QWebEngineView>
#include <QDesktopServices>

class MyQWebEnginePage : public QWebEnginePage
{
    Q_OBJECT

public:
    MyQWebEnginePage(QObject* parent = 0) : QWebEnginePage(parent){}

    bool acceptNavigationRequest(const QUrl & url,QWebEnginePage::NavigationType type,bool isMainFrame)
    {
         qDebug() << "acceptNavigationRequest("<<url << "," << type << "," << isMainFrame<<")";

        if (type == QWebEnginePage::NavigationTypeLinkClicked)
        {
            QDesktopServices::openUrl(url);
            return false;
        }
        return true;
    }
};


class MyQWebEngineView : public QWebEngineView
{
    Q_OBJECT
public:
    MyQWebEngineView(QWidget* parent = 0);
    MyQWebEnginePage* page() const;

};

#endif // MYQWEBENGINEVIEW_H

解决方法

你不需要第二部分.试试这个:

QWebEngineView *view = new QWebEngineView();
MyQWebEnginePage *page = new MyQWebEnginePage();
view->setPage(page);

我们今天的关于从 QWebEngineView 自动登录到网站qt打开网页 自动登录的分享已经告一段落,感谢您的关注,如果您想了解更多关于asp.net – RazorViewEngine.FindView无法找到预编译的视图、asp.net-mvc – 单元测试ViewEngines.Engines.FindView的正确方法是什么?、c – QWebEnginePage中的透明背景、c – QWebEngineView在外部浏览器中打开的相关信息,请在本站查询。

本文标签: