如何用Python+Selenium测试文件下载及验证下载结果?
解决Selenium Chrome下载文件的验证问题
下面是直接可用的实现步骤和代码:
1. 配置Chrome下载参数
先指定专属的测试下载目录,避免和系统默认下载文件夹的文件混淆,同时关闭下载弹窗让文件自动保存:
from selenium import webdriver from selenium.webdriver.chrome.options import Options import os # 创建测试用下载文件夹(不存在则自动创建) download_dir = os.path.join(os.getcwd(), "test_downloads") os.makedirs(download_dir, exist_ok=True) chrome_options = Options() chrome_options.add_experimental_option("prefs", { "download.default_directory": download_dir, "download.prompt_for_download": False, # 关闭下载确认弹窗 "download.directory_upgrade": True, "safebrowsing.enabled": True # 允许下载安全文件 }) driver = webdriver.Chrome(options=chrome_options)
2. 等待下载完成的核心逻辑
Chrome下载时会生成带.crdownload后缀的临时文件,下载完成后自动移除该后缀。我们可以循环检测目录,直到找到目标文件或超时:
import time def wait_for_download(download_dir, target_suffix=None, timeout=30): """ 等待文件下载完成 :param download_dir: 下载目录路径 :param target_suffix: 目标文件后缀(如.xlsx/.pdf),传None则等待所有临时文件消失 :param timeout: 超时时间(秒) """ start_time = time.time() while time.time() - start_time < timeout: for filename in os.listdir(download_dir): file_path = os.path.join(download_dir, filename) if os.path.isdir(file_path): continue # 匹配目标后缀且排除临时文件 if target_suffix: if filename.endswith(target_suffix) and not filename.endswith(".crdownload"): return file_path # 未指定后缀时,只要不是临时文件就返回 else: if not filename.endswith(".crdownload"): return file_path time.sleep(1) raise TimeoutError(f"下载超时,超过{timeout}秒未找到目标文件")
使用示例:
# 触发下载(替换成你的页面元素定位逻辑) driver.get("你的下载页面URL") download_link = driver.find_element(By.XPATH, "//a[contains(text(),'下载')]") download_link.click() # 等待PDF文件下载完成 downloaded_file = wait_for_download(download_dir, target_suffix=".pdf") print(f"下载完成,文件路径:{downloaded_file}")
3. 验证文件类型(两种方案)
方案1:检查文件后缀(简单场景)
直接判断文件名后缀,适合不需要高精度验证的场景:
def check_file_suffix(file_path, expected_suffix): return file_path.lower().endswith(expected_suffix.lower()) # 验证是否为PDF文件 if check_file_suffix(downloaded_file, ".pdf"): print("文件类型符合预期") else: print("文件类型不符合预期")
方案2:读取文件头判断真实类型(高精度)
通过文件二进制头标识判断真实类型,避免后缀伪造的情况:
def get_real_file_type(file_path): # 常见文件的二进制头映射 file_signatures = { b"%PDF-": "PDF", b"PK\x03\x04": "Excel/Word(ZIP格式)", b"\xFF\xD8\xFF": "JPEG", b"GIF89a": "GIF", b"BM": "BMP" } with open(file_path, "rb") as f: header = f.read(10) # 读取前10字节足够判断大部分类型 for sig, file_type in file_signatures.items(): if header.startswith(sig): return file_type return "未知类型" # 验证真实类型 real_type = get_real_file_type(downloaded_file) if real_type == "PDF": print("文件真实类型为PDF,符合预期") else: print(f"文件真实类型为{real_type},不符合预期")
4. 测试后清理(可选)
测试完成后可删除下载文件,避免占用空间:
os.remove(downloaded_file)
内容的提问来源于stack exchange,提问作者s.l
相关产品推荐
相关产品推荐

