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

如何在Selenium(Python+Firefox)中读取网页桌面推送通知?

可行,通过Hook JavaScript API完全可以实现

核心思路

网页发送桌面推送通知依赖浏览器的Notification API(包括Service Worker的showNotification方法),我们可以通过注入自定义JavaScript脚本重写这些API,将通知内容捕获到全局变量中,再通过Selenium读取该变量即可。同时,针对"失焦才触发通知"的要求,可以通过重写document.hasFocus()让网页判定当前窗口处于失焦状态。

具体实现步骤

  1. 配置Firefox无头模式并启用通知权限
    首先需要确保Firefox允许发送通知,避免权限拦截。

  2. 注入Hook脚本捕获通知

    • 重写原生Notification构造函数,将通知的标题、正文、选项等信息存入全局数组。
    • 针对Service Worker推送的通知,额外HookServiceWorkerRegistration.prototype.showNotification方法。
    • 重写document.hasFocus()返回false,模拟窗口失焦状态。
  3. 读取捕获的通知内容
    通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:28:28