Selenium Chrome下载PDF后isfile判定非文件异常排查
异常原因
- 路径处理存在两处错误:
- 配置Chrome下载路径时用的是绝对路径
/tmp/download-dir,但遍历文件时写的是相对路径tmp/download-dir,开头缺失根目录标识/,两个路径指向的存储位置完全不同 - 拼接文件路径时直接把目录字符串和文件名做字符串相加,没有补充路径分隔符,最终生成的路径格式为
tmp/download-dir[文件名],比如文件名为patent.pdf时,拼接结果是tmp/download-dirpatent.pdf,和实际文件存储路径不匹配,自然会被os.path.isfile()判定为非文件,调用os.stat()时因为路径不存在抛出OSError
- 配置Chrome下载路径时用的是绝对路径
- 缺少下载完成等待逻辑:Chrome在文件下载过程中会生成后缀为
.crdownload的临时缓存文件,直到文件全部写入完成才会重命名为正式的PDF文件。如果页面刚触发下载就立刻遍历目录,要么会碰到还在写入的临时文件,要么正式PDF文件还没生成,也会触发检测异常。
修复方案
- 统一路径写法,用标准库方法拼接路径
不要手动硬编码路径分隔符,直接用os.path模块的方法处理路径,自动适配不同操作系统的路径规则,同时保证下载目录变量和Chrome配置里的路径完全一致:import os # 统一定义下载目录,和Chrome prefs里的配置完全一致 DOWNLOAD_PATH = "/tmp/download-dir" # 遍历文件示例 for file_name in os.listdir(DOWNLOAD_PATH): # 用os.path.join拼接路径,自动补充分隔符 file_full_path = os.path.join(DOWNLOAD_PATH, file_name) if os.path.isfile(file_full_path): print(f"检测到文件:{file_full_path}") else: print(f"非有效文件:{file_full_path}") - 增加下载完成轮询逻辑
触发下载后不要立刻读取文件,循环检测目录内的文件状态,直到确认正式PDF文件写入完成再做后续操作,参考实现:import time import os DOWNLOAD_PATH = "/tmp/download-dir" MAX_WAIT_SEC = 30 # 最长等待30秒,可根据网络情况调整 start_ts = time.time() target_pdf_path = None while time.time() - start_ts < MAX_WAIT_SEC: current_files = os.listdir(DOWNLOAD_PATH) for f in current_files: # 过滤临时下载文件,匹配PDF后缀 if f.endswith(".pdf") and not f.endswith(".crdownload"): full_path = os.path.join(DOWNLOAD_PATH, f) # 连续两次检测文件大小一致、且大于0,说明写入完成 try: size_first = os.stat(full_path).st_size time.sleep(1) size_second = os.stat(full_path).st_size if size_first == size_second and size_first > 0: target_pdf_path = full_path break except OSError: # 文件被占用时跳过,下一轮再检测 continue if target_pdf_path: break time.sleep(0.5) if target_pdf_path: print(f"PDF下载完成,路径:{target_pdf_path},大小:{os.stat(target_pdf_path).st_size}字节") else: raise TimeoutError("PDF下载超时,未检测到有效文件")
额外提示:如果运行环境开启了SELinux或者目录权限限制,需要保证运行Python脚本的用户对
/tmp/download-dir目录有读写权限,否则也会出现文件写入成功但无法读取的异常。
内容的提问来源于stack exchange,提问作者Rico
相关产品推荐
相关产品推荐

