You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何捕获QWebEngineView发起的HTTP请求?

修复QWebEngineView请求拦截与页面渲染问题

我想把QWebEngineView在导航时发送的所有HTTP请求(GET、POST等)保存到文件,就像Firefox里「检查 > 网络 > 保存为HAR文件」那样。我试了两段代码,目前只想先打印出请求,但都有问题:

  • 第一段脚本能正常显示页面,但无法拦截请求
  • 第二段脚本能捕获并显示请求,但窗口无法渲染

原始代码

第一段脚本(可渲染,无拦截)

# SCRIPT 1

import sys
from PyQt6.QtCore import *
from PyQt6.QtWebEngineCore import *
from PyQt6.QtWidgets import *
from PyQt6.QtWebEngineWidgets import *


class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
    def interceptRequest(self, info: QWebEngineUrlRequestInfo):
        print()
        print("interceptRequest")
        print(info.requestUrl())
        print(info.requestMethod())


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        interceptor = WebEngineUrlRequestInterceptor()
        self.profile = QWebEngineProfile.defaultProfile()
        self.profile.setUrlRequestInterceptor(interceptor)
        print(self.profile)
        self.browser = QWebEngineView(self.profile, parent=self)

        self.setCentralWidget(self.browser)

        self.browser.setUrl(QUrl("https://google.com"))
        self.show()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    app.exec()

第二段脚本(可拦截,无渲染)

# SCRIPT 2

import sys
from PyQt6.QtCore import *
from PyQt6.QtWebEngineCore import *
from PyQt6.QtWebEngineWidgets import *
from PyQt6.QtWidgets import *


class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
    def interceptRequest(self, info: QWebEngineUrlRequestInfo):
        print()
        print("interceptRequest")
        print(info.requestUrl())
        print(info.requestMethod())


class MyWebEnginePage(QWebEnginePage):
    def acceptNavigationRequest(self, url, _type, isMainFrame):
        print("acceptNavigationRequest")
        print(url)
        return QWebEnginePage.acceptNavigationRequest(self, url, _type, isMainFrame)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    browser = QWebEngineView()
    interceptor = WebEngineUrlRequestInterceptor()
    profile = QWebEngineProfile()
    profile.setUrlRequestInterceptor(interceptor)
    page = MyWebEnginePage(profile)
    page.setUrl(QUrl("https://google.com"))
    browser.setPage(page)
    browser.showMaximized()
    app.exec()

问题原因

  1. 第一段脚本问题:QWebEngineProfile.defaultProfile()是全局默认配置,可能在你设置拦截器之前就已经被Qt内部初始化完成,此时再绑定拦截器不会生效。
  2. 第二段脚本问题:创建QWebEngineProfile时未指定父对象,Python的垃圾回收机制会提前回收这个Profile对象,导致依赖它的页面无法正常渲染。

修复方案

方案一:修复第一段脚本(自定义Profile)

改用自定义Profile替代默认配置,确保拦截器在Profile被使用前就完成绑定:

import sys
from PyQt6.QtCore import QUrl
from PyQt6.QtWebEngineCore import QWebEngineUrlRequestInterceptor, QWebEngineUrlRequestInfo, QWebEngineProfile
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6.QtWebEngineWidgets import QWebEngineView


class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
    def interceptRequest(self, info: QWebEngineUrlRequestInfo):
        print("\n=== 拦截到HTTP请求 ===")
        print(f"请求地址: {info.requestUrl().toString()}")
        print(f"请求方法: {info.requestMethod().data().decode()}")


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 创建自定义Profile并绑定父对象,避免被提前回收
        self.profile = QWebEngineProfile("custom_request_profile", self)
        self.interceptor = WebEngineUrlRequestInterceptor()
        self.profile.setUrlRequestInterceptor(self.interceptor)
        
        self.browser = QWebEngineView(self)
        # 为浏览器页面设置自定义Profile
        page = self.browser.page()
        page.setProfile(self.profile)
        
        self.setCentralWidget(self.browser)
        self.browser.setUrl(QUrl("https://google.com"))
        self.show()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    app.exec()

方案二:修复第二段脚本(给Profile加父对象)

给QWebEngineProfile指定父对象,确保其生命周期与浏览器视图一致:

import sys
from PyQt6.QtCore import QUrl
from PyQt6.QtWebEngineCore import QWebEngineUrlRequestInterceptor, QWebEngineUrlRequestInfo, QWebEngineProfile
from PyQt6.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
from PyQt6.QtWidgets import QApplication


class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
    def interceptRequest(self, info: QWebEngineUrlRequestInfo):
        print("\n=== 拦截到HTTP请求 ===")
        print(f"请求地址: {info.requestUrl().toString()}")
        print(f"请求方法: {info.requestMethod().data().decode()}")


class MyWebEnginePage(QWebEnginePage):
    def acceptNavigationRequest(self, url, _type, isMainFrame):
        print("\n=== 导航请求触发 ===")
        print(f"导航地址: {url.toString()}")
        return super().acceptNavigationRequest(url, _type, isMainFrame)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    browser = QWebEngineView()
    interceptor = WebEngineUrlRequestInterceptor()
    # 给Profile设置父对象为浏览器视图,防止被垃圾回收
    profile = QWebEngineProfile("custom_profile", browser)
    profile.setUrlRequestInterceptor(interceptor)
    page = MyWebEnginePage(profile)
    page.setUrl(QUrl("https://google.com"))
    browser.setPage(page)
    browser.showMaximized()
    app.exec()

后续扩展(生成HAR文件)

如果要实现类似Firefox的HAR文件保存,可以在interceptRequest方法中收集请求的详细信息(如请求头、参数、响应数据等),按照HAR文件格式规范组织成JSON结构,最后写入文件即可。

内容的提问来源于stack exchange,提问作者zigma12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 23:48:18