プロキシを使用せずQWebViewの通信を覗き見る方法を記載。
PyQt5を使っているがC++等でも大きくは違わないはず。
試行錯誤の結果なので改善点あれば指摘ください。
QNetworkAccessManager
を継承する
# コード例
class MyNetworkAccessManager(QNetworkAccessManager):
def __init__(self, parent):
super(NetworkAccessManager, self).__init__(parent)
self.reply_content = {}
# 以下後述
self.reply_content
は受信内容の保持に使用
QWebPage.setNetworkAccessManager()
で上記クラスをQWebPage
に設定する
# コード例
nm = MyNetworkAccessManager()
web_view = QWebView()
web_view.page().setNetworkAccessManager(nm)
これでweb_view
の通信はMyNetworkAccessManager
経由で行われることになる。
送信を覗き見る
QNetworkAccessManager.createRequest()
をオーバーライドして送信を覗き見る。
# コード例
class MyNetworkAccessManager(QNetworkAccessManager):
# __init__は省略
def createRequest(self, op, req, outgoing_data = None):
if outgoing_data is not None:
content = str(outgoing_data.peek(1024*1024), encoding='utf-8'))
reply = super(MyNetworkAccessManager, self).createRequest(op, req, outgoing_data)
reply.readyRead.connect(self.on_ready_read)
reply.finished.connect(self.on_finished)
self.reply_content[reply] = ''
return reply
content
に送信内容が入る。ただしGETやHEADの場合は空。
outgoing_data
はQIODevice
だが、bytesAvailable()
等のメソッドが軒並み0を返してくるので固定値でpeek()
を呼んでいる。
peek()
はバイト列を返す。ここではエンコーディングをutf-8固定で文字列にしているが、状況に合わせて適当に。
あと受信内容取得のためにreadyRead
,finished
シグナルをconnect
している。
受信を覗き見る
# コード例
class MyNetworkAccessManager(QNetworkAccessManager):
# __init__, createRequest 省略
def _get_content(self, reply):
content = str(reply.peek(reply.bytesAvailable()), encoding='utf-8')
self.reply_content[reply] += content
@pyqtSlot()
def on_ready_read(self):
reply = self.sender()
self._get_content(reply)
@pyqtSlot()
def on_finished(self):
reply = self.sender()
self._get_content(reply)
content = self.reply_content[reply]
del self.reply_content[reply]
readyRead
シグナルの度peek()
でデータを取り出し辞書に保持。finished
シグナルで辞書からデータ全体を取得している。
_get_content()
もutf-8決め打ちしてあるが、状況に合わせて適当に。