如何在Arch Linux平台的PyQt5应用中嵌入Selenium浏览器
Arch Linux平台PyQt5嵌入Selenium控制Chrome实现方案
依赖安装
首先安装Arch系统所需的基础依赖:
sudo pacman -S --needed python-pyqt5 python-selenium python-webdriver-manager chromium xorg-server xorg-xprop
如果使用Wayland桌面环境(GNOME默认、KDE可选),不需要额外安装组件,后续启动参数会配置Chrome强制兼容X11协议。
实现思路
- 启动Chrome时直接指定窗口位置到屏幕外区域,彻底解决嵌入前窗口可见的问题
- 通过Chrome DevTools协议(CDP)直接获取对应Selenium窗口的X11原生整数窗口ID,替代Windows下win32gui枚举方案,不需要匹配窗口标题,准确率更高
- 用Qt原生
fromWinId接口嵌入窗口,逻辑和原有Windows版本对齐,适配性更强
完整实现代码
from PyQt5 import QtCore, QtGui, QtWidgets from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.options import Options import time class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(1200, 800) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") MainWindow.setCentralWidget(self.centralwidget) # 配置Chrome启动参数 self.chrome_options = Options() self.chrome_options.add_argument("disable-infobars") self.chrome_options.add_argument("--no-first-run") self.chrome_options.add_argument("--no-default-browser-check") # 强制X11后端,兼容Wayland桌面环境 self.chrome_options.add_argument("--ozone-platform=x11") # 启动时窗口放到屏幕外,避免嵌入前可见 self.chrome_options.add_argument("--window-position=-30000,-30000") # 禁用GPU加速避免部分场景渲染异常 self.chrome_options.add_argument("--disable-gpu") # 启动目标页面 target_url = "http://www.in.gr" self.chrome_options.add_argument(f"--app={target_url}") # 启动Chrome驱动 self.s = Service(ChromeDriverManager().install()) self.driver = webdriver.Chrome(service=self.s, options=self.chrome_options) self.driver.get(target_url) # 等待窗口初始化完成 time.sleep(1) # 通过CDP协议获取X11原生窗口ID cd_window_id = self.driver.current_window_handle target_info = self.driver.execute_cdp_cmd("Target.getTargetInfo", {"targetId": cd_window_id}) x11_window_id = target_info["targetInfo"]["windowId"] # 嵌入Qt窗口 self.embed_window = QtGui.QWindow.fromWinId(x11_window_id) self.embed_widget = QtWidgets.QWidget.createWindowContainer(self.embed_window) self.verticalLayout.addWidget(self.embed_widget) # 调整Chrome窗口大小适配容器 self.driver.set_window_size(MainWindow.width(), MainWindow.height()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "Chrome嵌入式窗口")) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_())
注意事项
- 如果系统安装的Chromium版本和webdriver-manager自动下载的驱动版本不匹配,可以手动指定驱动版本,或者直接安装Arch源里的
chromedriver包,修改Service路径为/usr/bin/chromedriver即可 - 嵌入后窗口的输入、渲染完全由Chrome处理,和原生浏览器体验一致,支持所有Selenium控制操作
- 如果需要隐藏Chrome的标题栏,可以在启动参数里加
--start-fullscreen或者--kiosk
内容的提问来源于stack exchange,提问作者Chris P
相关产品推荐
相关产品推荐

