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

如何通过Selenium控制Flask服务中生成的下载文件?

解决Flask+Selenium高并发下的下载文件管控问题

以下是针对你的场景的可行方案,完全适配高并发环境下每个请求专属一个下载文件的需求:

1. 为每个请求分配独立的专属下载目录

这是最直接的隔离方案,彻底避免文件混淆:

  • 处理请求时,生成唯一标识(比如uuid.uuid4().hex)作为专属目录名,创建临时目录(可使用tempfile.mkdtemp)
  • 配置Selenium浏览器的下载路径为该专属目录,同时禁用下载弹窗
  • 下载完成后,直接从该目录获取文件,无需遍历或判断修改时间
  • 请求处理完毕后,可选择删除临时目录释放空间

示例代码:

import uuid
import tempfile
import os
import shutil
from flask import Flask, request
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

app = Flask(__name__)

@app.route('/download', methods=['POST'])
def handle_download():
    # 生成专属临时目录
    download_dir = tempfile.mkdtemp(prefix=f"req_{uuid.uuid4().hex}_")
    # 配置Chrome下载参数
    chrome_options = Options()
    prefs = {
        "download.default_directory": download_dir,
        "download.prompt_for_download": False,
        "download.directory_upgrade": True,
        "safebrowsing.enabled": True
    }
    chrome_options.add_experimental_option("prefs", prefs)
    # 启动浏览器执行操作
    driver = webdriver.Chrome(options=chrome_options)
    try:
        # 执行Selenium操作,触发下载
        driver.get("https://example.com/download-page")
        driver.find_element("id", "download-btn").click()
        # 等待下载完成(可根据文件类型/大小设置合理等待逻辑)
        # 直接从专属目录获取目标文件(目录内仅该请求的文件)
        downloaded_files = os.listdir(download_dir)
        if downloaded_files:
            target_file = os.path.join(download_dir, downloaded_files[0])
            # 这里添加文件管控逻辑
            # ...
    finally:
        driver.quit()
        # 清理临时目录(需保留文件则跳过此步骤)
        shutil.rmtree(download_dir)
    return "处理完成"

2. 通过Chrome DevTools协议主动捕获下载事件

利用Selenium的CDP(Chrome DevTools Protocol)监听下载开始事件,直接获取文件名,无需依赖目录扫描:

  • 监听Network.downloadWillBegin事件,该事件会返回下载文件的路径和文件名
  • 每个请求的浏览器实例独立监听,不会和其他请求的事件混淆

示例代码片段:

# 启动浏览器后开启CDP监听
driver.execute_cdp_cmd("Network.enable", {})
downloaded_file_path = None

def handle_download_event(event):
    global downloaded_file_path
    # 从事件参数中提取下载文件路径
    downloaded_file_path = event.get("params", {}).get("path")

# 注册事件监听
driver.add_event_listener("Network.downloadWillBegin", handle_download_event)

# 执行触发下载的操作
driver.find_element("id", "download-btn").click()

# 等待下载完成后,直接使用downloaded_file_path操作文件
# ...

3. 主动指定下载文件名(若场景允许)

如果下载资源支持自定义文件名,可以通过修改请求或页面元素强制指定:

  • 若下载通过点击链接触发,可通过JavaScript修改链接的download属性
  • 若通过API请求下载,可利用CDP修改响应头的Content-Disposition字段,指定filename

示例代码(修改链接download属性):

# 找到下载链接,设置自定义文件名
download_link = driver.find_element("id", "download-btn")
target_filename = f"req_{uuid.uuid4().hex}_data.csv"
driver.execute_script("arguments[0].setAttribute('download', arguments[1]);", download_link, target_filename)
# 点击下载,此时文件名即为预先指定的target_filename
download_link.click()

高并发注意事项

  • 确保每个请求的Selenium实例独立,避免共享浏览器上下文
  • 可使用线程池/进程池管理Selenium实例,防止资源耗尽
  • 及时清理临时文件或目录,避免磁盘空间溢出

内容的提问来源于stack exchange,提问作者Diego Cândido

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:37:23