如何在Selenium(Python+Firefox)中读取网页桌面推送通知?
可行,通过Hook JavaScript API完全可以实现
核心思路
网页发送桌面推送通知依赖浏览器的Notification API(包括Service Worker的showNotification方法),我们可以通过注入自定义JavaScript脚本重写这些API,将通知内容捕获到全局变量中,再通过Selenium读取该变量即可。同时,针对"失焦才触发通知"的要求,可以通过重写document.hasFocus()让网页判定当前窗口处于失焦状态。
具体实现步骤
配置Firefox无头模式并启用通知权限
首先需要确保Firefox允许发送通知,避免权限拦截。注入Hook脚本捕获通知
- 重写原生
Notification构造函数,将通知的标题、正文、选项等信息存入全局数组。 - 针对Service Worker推送的通知,额外Hook
ServiceWorkerRegistration.prototype.showNotification方法。 - 重写
document.hasFocus()返回false,模拟窗口失焦状态。
- 重写原生
读取捕获的通知内容
通过Selenium执行JavaScript,从全局变量中提取已捕获的通知数据。
完整代码示例
from selenium import webdriver from selenium.webdriver.firefox.options import Options import time from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 配置Firefox无头环境 firefox_options = Options() firefox_options.add_argument('--headless') firefox_options.add_argument('--no-sandbox') firefox_options.add_argument('--disable-dev-shm-usage') firefox_options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36') firefox_options.add_argument('--disable-blink-features=AutomationControlled') # 启用通知权限 firefox_options.set_preference('dom.webnotifications.enabled', True) firefox_options.set_preference('dom.webnotifications.serviceworker.enabled', True) firefox_options.set_preference('permissions.default.desktop-notification', 1) # 1 = 允许通知 driver = webdriver.Firefox(options=firefox_options) # 注入通知捕获Hook脚本 hook_script = """ // 初始化全局数组存储通知 window.capturedNotifications = []; // Hook 原生Notification构造函数 const originalNotification = window.Notification; window.Notification = function(title, options) { window.capturedNotifications.push({ title: title, options: options || {}, source: 'direct' }); return new originalNotification(title, options); }; // Hook Service Worker的showNotification方法 if ('serviceWorker' in navigator) { const originalSWShow = ServiceWorkerRegistration.prototype.showNotification; ServiceWorkerRegistration.prototype.showNotification = function(title, options) { window.capturedNotifications.push({ title: title, options: options || {}, source: 'service-worker' }); return originalSWShow.call(this, title, options); }; } // 自动授权通知权限 Notification.requestPermission = async () => 'granted'; // 模拟窗口失焦 Object.defineProperty(document, 'hasFocus', { value: () => false, writable: false }); """ driver.execute_script(hook_script) # 访问目标网页 driver.get('https://your-target-site.com') # 用显式等待替代固定休眠,等待通知出现 try: WebDriverWait(driver, 20).until( lambda d: d.execute_script('return window.capturedNotifications.length > 0;') ) except: print("超时未捕获到通知") # 获取捕获的所有通知 captured_notes = driver.execute_script('return window.capturedNotifications;') # 输出通知内容 if captured_notes: for i, note in enumerate(captured_notes): print(f"=== 通知 {i+1} ===") print(f"来源: {note['source']}") print(f"标题: {note['title']}") print(f"正文: {note['options'].get('body', '无正文')}") print(f"图标: {note['options'].get('icon', '无图标')}") else: print("未捕获到任何通知") driver.quit()
注意事项
- 如果网页存在反爬机制,
--disable-blink-features=AutomationControlled参数可以规避大部分无头模式检测。 - 若通知是通过第三方SDK发送的,需要根据实际调用的API调整Hook逻辑。
- 显式等待比固定休眠更可靠,能有效适配不同网页的加载速度。
内容的提问来源于stack exchange,提问作者sawntoe
相关产品推荐
相关产品推荐

