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

使用Selenium下载文件时如何获取实际保存的正确文件名?

你遇到的文件名与a标签文本不一致的问题,本质是服务端为了避免重名、做缓存标识等需求,在下载响应时动态追加了时间戳后缀,该后缀不会提前暴露在前端a标签的属性或文本中,因此需要从下载链路的下游环节获取真实文件名,以下是三种可行方案:


方案1:拦截下载请求的响应头获取

  • 核心逻辑:下载请求的响应头Content-Disposition字段会携带服务端指定的最终文件名,直接读取该字段即可拿到准确名称。
  • 实现依赖:需要用selenium-wire替换原生Selenium实现网络请求拦截,示例代码如下:
from seleniumwire import webdriver

driver = webdriver.Chrome()
driver.get("你的目标页面地址")

link1 = driver.find_element_by_xpath("//a[@id='rfq-display-attachment-0']")
# 提前获取下载链接用于后续请求匹配
target_href = link1.get_attribute('href')
link1.click()

# 遍历拦截到的请求匹配对应下载请求
for request in driver.requests:
    if request.url == target_href and request.response:
        # 解析Content-Disposition字段
        content_disposition = request.response.headers.get('Content-Disposition', '')
        if 'filename=' in content_disposition:
            # 提取文件名并去掉前后引号
            real_filename = content_disposition.split('filename=')[1].strip('"')
            print(real_filename)
            break
  • 注意事项:如果下载链接有302跳转,可以匹配跳转后的最终请求地址即可。

方案2:监听下载目录的文件变化

  • 核心逻辑:浏览器下载文件时会先生成后缀为.crdownload(Chrome)/.part(Firefox)的临时文件,下载完成后才会重命名为最终文件名,只需监控下载目录等待文件落地即可拿到真实名称,该方案兼容性最强,不需要修改请求逻辑。
  • 示例代码:
import os
import time

# 替换为你的浏览器默认下载目录路径
DOWNLOAD_DIR = "/Users/xxx/Downloads"

# 点击下载前记录目录现有文件列表
before_download = set(os.listdir(DOWNLOAD_DIR))
link1.click()

# 等待下载完成,超时时间30秒可自行调整
timeout = 30
start_time = time.time()
real_filename = None
while time.time() - start_time < timeout:
    after_download = set(os.listdir(DOWNLOAD_DIR))
    new_files = after_download - before_download
    # 过滤未完成的临时文件
    valid_files = [f for f in new_files if not f.endswith('.crdownload') and not f.endswith('.part')]
    if valid_files:
        # 如果同时有多个文件下载,可以增加前缀匹配逻辑过滤
        real_filename = [f for f in valid_files if f.startswith('BEHR SDS')][0]
        break
    time.sleep(1)

print(real_filename)

方案3:调用Chrome DevTools Protocol(CDP)获取下载信息

  • 核心逻辑:如果你使用Chrome/Edge内核浏览器,可以直接调用浏览器内置的CDP接口监听下载事件,能直接拿到浏览器确认的最终下载文件名,不需要解析请求也不需要扫描目录。
  • 示例代码:
from selenium import webdriver
import time

driver = webdriver.Chrome()
# 启用Downloads域事件监听
driver.execute_cdp_cmd('Page.enable', {})
driver.execute_cdp_cmd('Downloads.enable', {})

real_filename = None
# 绑定下载事件回调,拿到文件名
def on_download_begin(params):
    global real_filename
    real_filename = params['suggestedFilename']
driver.add_cdp_listener('Downloads.downloadWillBegin', on_download_begin)

# 点击触发下载
link1.click()
# 等待事件触发
while not real_filename:
    time.sleep(0.5)
print(real_filename)

内容的提问来源于stack exchange,提问作者Rikky Bhai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 03:36:07