1

How to Open URL with POST method in QWebEnginePage-pyqt5, I also need to read and post a cookie with every request.

def __init__(self, url):
    self.app = QApplication(sys.argv)
    QWebEnginePage.__init__(self)
    self.html = ''
    self.loadFinished.connect(self._on_load_finished)
    self.load(QUrl(url))
    self.app.exec_()

def _on_load_finished(self):
    self.html = self.toHtml(self.Callable)

def Callable(self, html_str):
    self.html = html_str
    self.app.quit()
Isma
  • 14,604
  • 5
  • 37
  • 51
marcelo.delta
  • 2,730
  • 5
  • 36
  • 71

1 Answers1

2

You cannot make a POST request with QWebEnginePage unless you use Javascript.

Here is an example of how to do it with Qt classes (haven't tested it, but should work).

First we make a get request to get the cookie (you need to provide a specific URL for this), then we store the cookie for the target address and perform the post request with some data:

from PyQt5.QtCore import pyqtSignal, QUrl, QUrlQuery
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest,QNetworkCookieJar


class NetworkManager(QNetworkAccessManager):
    requestFinished = pyqtSignal(QNetworkReply)

    def __init__(self):
        super().__init__()

    def finished(self, reply):
        super().finished(reply)
        self.requestFinished.emit(reply)


class Request:
    def __init__(self):
        super().__init__()

        self.network_manager = NetworkManager()
        self.network_manager.requestFinished.connect(self.request_finished)

        self.network_manager.setCookieJar(QNetworkCookieJar())

        self.url = ''
        self.cookie_url = ''

    def _read_cookie(self):
        request = QNetworkRequest(QUrl(self.cookie_url))
        request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded")
        self.network_manager.get(request)

    def _post(self):
        post_data = QUrlQuery()
        post_data.addQueryItem("param1", "value")
        post_data.addQueryItem("param2", "value")

        request = QNetworkRequest(QUrl(self.url))
        request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded")

         self.network_manager.post(request, post_data.toString(QUrl.FullyEncoded).toUtf8())

    def post_request(self, url, cookie_url):
        self.url = url
        self.cookie_url = cookie_url

        self._read_cookie()

    def request_finished(self, reply: QNetworkReply):
        reply.deleteLater()

        cookies = reply.header(QNetworkRequest.SetCookieHeader)
        if cookies:
            self.network_manager.cookieJar().setCookiesFromUrl(cookies, self.url)

        self._post()

Note that this implementation is not thread-safe.

Also, there are simpler ways to do this in Python, using requests:

How to send cookies in a post request with the Python Requests library?

Isma
  • 14,604
  • 5
  • 37
  • 51
  • The page you intend to load has javascript that needs to be executed. The requests do this? I don't think so. Thank you very much for your attention, I am very grateful for the support. I will read this code now. – marcelo.delta Jan 29 '19 at 14:11
  • You should write all the requirements, such as the one you just described! Otherwise it's very difficult to help. Maybe you need to look into selenium to do what you want. That code will get a cookie that you can reuse on your post call to keep the session but it will not run any javascript, that is done client side. – Isma Jan 29 '19 at 14:13