Запрос POST с использованием запроса QWebView

Привет, я работаю с pyqt4, и я хочу создать произвольный запрос POST, используя запрос QtWebKit моего QWebPage/QWebView. Тщательно осмотрев все вокруг, я понял, что мне нужно создать подкласс networkaccessmanager, переопределив метод createRequest().

Я видел пример, который позволял использовать четвертый параметр createRequest для извлечения данных отправляемого запроса POST (см. код ниже), но мой вопрос заключается в том, как я могу установить ту же переменную данных createRequest для отправки пользовательских данных POST, как "запрос = мое значение"?

По-видимому, данные - это переменная QIODevice: я пробовал много разных способов установить ее, но не могу заставить ее работать и всегда заканчиваю тем, что python жалуется на неожиданное значение. Я что-то упустил здесь? Кто-нибудь хочет поделиться образцом рабочего кода?

import sys  
from PySide.QtCore import *  
from PySide.QtGui import QApplication  
from PySide.QtWebKit import QWebView, QWebPage 
from PySide.QtNetwork import QNetworkAccessManager

html = '''  <html>  <body> 
    <form action="http://www.google.com" method="post"><input type="text" name="test" /><input type="submit" value="submit"/></form>
</body>  </html>  ''' 

class Browser(object):

    def __init__(self):
        self.network_manager = QNetworkAccessManager()
        self.network_manager.createRequest = self._create_request

        self.web_page = QWebPage()
        self.web_page.setNetworkAccessManager(self.network_manager)

        self.web_view = QWebView()
        self.web_view.setPage(self.web_page)

        self.html_data = None

    def _create_request(self, operation, request, data):
        # data contains all the post data that is being added to the request
        # so you can look into it here
        print data.readAll()
        reply = QNetworkAccessManager.createRequest(self.network_manager,
                                                    operation,
                                                    request,
                                                    data)
        return reply

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    browser = Browser() 
    frame = browser.web_page.mainFrame() 
    browser.web_view.setHtml(html) 
    browser.web_view.show() 
    app.exec_()

person bmfhoknt agooc    schedule 22.10.2012    source источник
comment
Вы хотите отправить совершенно новый запрос POST или изменить параметры существующего на лету?   -  person alexisdm    schedule 22.10.2012
comment
Ради знаний я хотел бы знать, как изменить параметры на лету для существующего, теперь, когда я знаю, как отправить новый запрос. Не стесняйтесь публиковать это здесь, я нигде не мог найти конкретной помощи, поэтому я уверен, что это принесет пользу и кому-то еще. Ваше здоровье.   -  person bmfhoknt agooc    schedule 22.10.2012


Ответы (1)


Код, который вы разместили, взят из одного из моих ответов, поэтому я чувствую себя обязанным ответить и на этот вопрос :)

from PySide.QtCore import QByteArray, QUrl
from PySide.QtGui import QApplication  
from PySide.QtWebKit import QWebView, QWebPage 
from PySide.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply


class Browser(object):

    def __init__(self):
        self.network_manager = QNetworkAccessManager()
        self.network_manager.createRequest = self._create_request
        self.network_manager.finished.connect(self._request_finished)

        self.web_page = QWebPage()
        self.web_page.setNetworkAccessManager(self.network_manager)

        self.web_view = QWebView()
        self.web_view.setPage(self.web_page)

    def _create_request(self, operation, request, data):
        print data.readAll()
        reply = QNetworkAccessManager.createRequest(self.network_manager,
                                                    operation,
                                                    request,
                                                    data)
        return reply

    def _request_finished(self, reply):
        if not reply.error() == QNetworkReply.NoError:
            # request probably failed
            print reply.error()
            print reply.errorString()

    def _make_request(self, url):
        request = QNetworkRequest()
        request.setUrl(QUrl(url))
        return request

    def _urlencode_post_data(self, post_data):
        post_params = QUrl()
        for (key, value) in post_data.items():
            post_params.addQueryItem(key, unicode(value))

        return post_params.encodedQuery()

    def perform(self, url, method='GET', post_data=dict()):
        request = self._make_request(url)

        if method == 'GET':
            self.web_view.load(request)
        else:
            encoded_data = self._urlencode_post_data(post_data)
            request.setRawHeader('Content-Type',
                                 QByteArray('application/x-www-form-urlencoded'))
            self.web_view.load(request,
                               QNetworkAccessManager.PostOperation,
                               encoded_data)

if __name__ == '__main__':
    app = QApplication([])
    browser = Browser()
    browser.perform('http://www.python.org', 'POST', {'test': 'value', 'anothername': 'gfdgfd'})
    app.exec_()
person andrean    schedule 22.10.2012
comment
Спасибо большое, Андрей, все работает. Я пробовал много разных вещей, но безуспешно, и теперь я вижу, что это было на самом деле менее тривиально, чем я думал. Еще раз огромное спасибо! :) - person bmfhoknt agooc; 22.10.2012
comment
ну, вы могли бы принять это как правильный ответ, если вы не возражаете :) - person andrean; 23.10.2012
comment
@andrean, пожалуйста, посмотрите и этот вопрос - stackoverflow .com/questions/37041316/, я знаю, что вам потребуется не больше минуты, чтобы решить проблему, спасибо - person ashish; 05.05.2016