使用 Selenium-Wire 捕获和分析前端网络请求

聖光之護
发布: 2025-11-07 11:51:01
原创
676人浏览过

使用 Selenium-Wire 捕获和分析前端网络请求

标准 selenium 并非为直接捕获 api 请求设计,但 `selenium-wire` 扩展了其功能,允许开发者在自动化测试中拦截、检查和分析浏览器与服务器之间的所有网络流量。本文将详细介绍如何利用 `selenium-wire` 捕获特定 api 请求及其 json 响应数据,从而在不改变页面 url 的情况下,获取前端后端交互的深层信息,适用于需要监控或验证 api 通信的自动化场景。

理解 Selenium 在 API 捕获中的局限性

Selenium 主要是一个浏览器自动化工具,用于模拟用户与网页的交互,如点击、输入、导航等。它关注的是用户可见的界面行为和页面状态变化。虽然可以通过 WebDriver 的日志(如 performance 日志)或执行 CDP(Chrome DevTools Protocol)命令来尝试获取网络请求信息,但这些方法通常较为复杂、不够直观,且可能依赖于特定浏览器或版本,维护成本较高。

当需求是捕获由前端行为(例如点击按钮)触发的后端 API 请求及其响应数据,特别是当页面 URL 不变而仅有 API 端点发生交互时,标准 Selenium 的能力显得捉襟见肘。此时,我们需要一个更专业的工具来直接监听和解析网络流量。

引入 Selenium-Wire:网络流量的监听器

selenium-wire 是一个 Python 库,它通过在 Selenium WebDriver 和浏览器之间设置一个代理(Proxy),从而能够拦截和检查所有流经浏览器的网络请求和响应。这使得开发者可以轻松地访问请求头、请求体、响应头和响应体,并对它们进行过滤和分析。

Selenium-Wire 的核心优势:

  • 透明代理: 无需额外配置浏览器代理,selenium-wire 会自动处理。
  • 全面捕获: 能够捕获所有类型的网络请求,包括 XHR/Fetch 请求、图片、CSS、JS 等。
  • 易于访问: 提供简洁的 API 来访问请求和响应的各个部分。
  • 灵活过滤: 可以根据 URL、方法、头信息等条件过滤请求。

安装与配置

首先,需要安装 selenium-wire 库。

ChatPDF
ChatPDF

使用ChatPDF,您的文档将变得智能!跟你的PDF文件对话,就好像它是一个完全理解内容的人一样。

ChatPDF 327
查看详情 ChatPDF

立即学习前端免费学习笔记(深入)”;

pip install selenium-wire
登录后复制

安装完成后,可以在 Python 代码中引入并配置 selenium-wire 的 WebDriver。

from selenium_wire import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import json
import time
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

def capture_api_response(start_url, element_id_to_click, api_url_part):
    """
    使用 selenium-wire 捕获点击元素后触发的 API 请求及其 JSON 响应。

    Args:
        start_url (str): 浏览器起始访问的 URL。
        element_id_to_click (str): 需要点击的元素的 ID。
        api_url_part (str): 目标 API URL 中包含的特定字符串,用于过滤请求。

    Returns:
        dict: 如果找到目标 API 的 JSON 响应,则返回解析后的字典;否则返回 None。
    """
    # 配置 WebDriver 选项
    options = webdriver.ChromeOptions()
    # 可以根据需要添加其他选项,例如无头模式
    # options.add_argument('--headless')
    # options.add_argument('--disable-gpu')

    # 配置 selenium-wire 的 WebDriver
    # service = Service(executable_path='/path/to/chromedriver') # 如果 chromedriver 不在 PATH 中,需要指定路径
    driver = webdriver.Chrome(options=options)
    driver.set_page_load_timeout(30) # 设置页面加载超时时间

    found_data = None

    try:
        logger.info(f"正在访问 URL: {start_url}")
        driver.get(start_url)

        # 清除所有历史请求,确保只捕获本次操作产生的流量
        driver.delete_all_requests()
        logger.info("已清除所有历史网络请求。")

        # 等待元素可点击并执行点击操作
        wait = WebDriverWait(driver, 10)
        element_to_click = wait.until(EC.element_to_be_clickable((By.ID, element_id_to_click)))
        logger.info(f"找到元素 '{element_id_to_click}',准备点击。")
        element_to_click.click()
        logger.info(f"已点击元素 '{element_id_to_click}'。")

        # 等待一段时间,让 API 请求有足够的时间完成并响应
        # 实际项目中,可能需要更智能的等待机制,例如等待某个特定的 DOM 元素出现或消失
        time.sleep(5)
        logger.info("等待 5 秒以捕获网络请求。")

        # 遍历所有捕获到的请求
        for request in driver.requests:
            # 确保请求有响应,并且响应 URL 包含目标 API 的部分
            if request.response and api_url_part in request.url:
                logger.info(f"捕获到潜在目标API请求: {request.url}")
                # 检查响应内容类型是否为 JSON
                content_type = request.response.headers.get('Content-Type', '')
                if 'application/json' in content_type:
                    try:
                        # 获取响应体并解码为 UTF-8 字符串,然后解析为 JSON
                        body = request.response.body.decode('utf-8')
                        json_data = json.loads(body)
                        logger.info(f"成功捕获并解析目标API JSON响应: {request.url}")
                        logger.info(f"响应数据示例: {json_data}")
                        found_data = json_data
                        break # 找到目标数据后即可停止遍历
                    except json.JSONDecodeError as e:
                        logger.warning(f"警告: 捕获到 JSON 类型响应但解析失败,URL: {request.url}, 错误: {e}")
                    except Exception as e:
                        logger.error(f"处理响应体时发生未知错误,URL: {request.url}, 错误: {e}")
                else:
                    logger.info(f"捕获到非 JSON 响应,URL: {request.url}, Content-Type: {content_type}")

        if not found_data:
            logger.info(f"未捕获到包含 '{api_url_part}' 的目标API请求及其 JSON 响应。")

    except Exception as e:
        logger.error(f"在执行过程中发生错误: {e}")
    finally:
        driver.quit()
        logger.info("浏览器已关闭。")

    return found_data

# --- 示例用法 ---
if __name__ == "__main__":
    # 替换为你的实际场景信息
    example_start_url = "https://www.example.com/data_page" # 假设你的页面URL
    example_element_id = "loadDataButton" # 假设点击这个ID的按钮会触发API请求
    example_api_url_part = "/api/v1/getData" # 假设你的API路径包含这个部分

    # 模拟一个简单的 HTML 页面,用于测试
    # 你需要手动创建一个这样的 HTML 文件或者有一个真实的页面
    # 例如,创建一个 `test_page.html` 文件:
    # ```html
    # <!DOCTYPE html>
    # <html>
    # <head>
    #     <title>Test Page</title>
    #     <script>
    #         function loadData() {
    #             fetch('/api/v1/getData', { method: 'GET' })
    #                 .then(response => response.json())
    #                 .then(data => {
    #                     document.getElementById('result').innerText = JSON.stringify(data, null, 2);
    #                     console.log('Data loaded:', data);
    #                 })
    #                 .catch(error => console.error('Error:', error));
    #         }
    #     </script>
    # </head>
    # <body>
    #     <h1>API Data Loader</h1>
    #     <button id="loadDataButton" onclick="loadData()">Load Data</button>
    #     <pre class="brush:php;toolbar:false;" id="result">
登录后复制
#

以上就是使用 Selenium-Wire 捕获和分析前端网络请求的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号