Python大循环中调用open()触发PermissionError权限问题求助
问题背景
你正在用Python+Selenium批量抓取400万份EDGAR SEC备案文件,逻辑是打开网页、全选复制文本、写入本地TXT文件。初期运行正常,但随机循环次数后,执行open()写入时触发PermissionError: [Errno 13] Permission denied。当前目录已生成16378个文件(1.7GB),磁盘剩余40GB,以管理员权限运行PyCharm,手动可创建文件,更换目录后恢复正常,怀疑是Windows与Python交互的文件数量限制。
核心循环代码如下:
driver = webdriver.Firefox(executable_path=path + '/codes_ml/geckodriver/geckodriver.exe') # initialize driver for row in range(1,num_urls): ticker = fund_reports_table.loc[row,"Ticker"] perioddate = fund_reports_table.loc[row,"Perioddater"] part = fund_reports_table.loc[row,"Part"] report_url = fund_reports_table.loc[row,"URL"] nbrparts= fund_reports_table.loc[row,"NbrParts"] filingdate = fund_reports_table.loc[row,"Filingdate"] driver.get(report_url) element = driver.find_element_by_css_selector("body") element.send_keys(Keys.CONTROL+'a') element.send_keys(Keys.CONTROL+'c') text = clipboard.paste() filename = ticker + "_" + filingdate + "_" + perioddate + "_" + str(part) + "of" + str(nbrparts) + ".txt" os.chdir("E:\\EDGAR_reports") output = open(filename, "wb") output.write(text.encode('utf-8', errors="ignore")) output.close() del output, text, perioddate, part, report_url, nbrparts, filingdate
排查方向
结合你的场景和Windows系统特性,这几个方向可以重点排查:
单个目录文件数量的隐性性能限制
NTFS单个目录理论支持数亿文件,但当文件数量过万后,Windows文件系统的读写性能会大幅下降,甚至出现系统层面的资源竞争,表现为看似“权限不足”的错误。建议按股票代码、日期拆分目录,比如给每个ticker单独建子目录,或按年份/季度归档,减少单个目录下的文件数量。文件句柄泄漏
虽然你手动调用了output.close(),但如果循环中某次执行出现异常(比如剪贴板读取失败、网页加载超时),close()可能不会被执行,导致文件句柄泄漏。时间一长,系统可用句柄耗尽就会触发权限错误。建议改用with语句自动管理文件句柄,即使报错也能确保文件关闭:# 把os.chdir移到循环外,只执行一次 os.chdir("E:\\EDGAR_reports") for row in range(1,num_urls): # ... 其他代码 ... with open(filename, "wb") as output: output.write(text.encode('utf-8', errors="ignore"))安全软件的实时扫描干扰
Windows杀毒软件、防火墙或第三方安全工具会实时扫描新创建的文件。短时间内创建大量文件时,安全软件可能会锁定正在扫描的文件,导致Python无法写入。可以临时关闭实时扫描测试,如果问题消失,就给E:\\EDGAR_reports目录添加安全软件白名单。Selenium/浏览器的资源泄漏
长时间运行Selenium循环,Firefox可能累积大量内存、进程或资源,间接影响系统的文件操作权限。建议定期重启浏览器,比如每处理1000个文件就重建driver:if row % 1000 == 0: driver.quit() driver = webdriver.Firefox(executable_path=path + '/codes_ml/geckodriver/geckodriver.exe')文件名非法字符问题
虽然你用字段拼接文件名,但某些Windows禁止的特殊字符(比如/、:、*等)可能未直接报错,却导致文件创建异常,后续触发权限问题。可以添加文件名清理逻辑:import re filename = re.sub(r'[\\/*?:"<>|]', '_', filename)
内容的提问来源于stack exchange,提问作者safex

