You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Python批量下载网站PDF遇权限错误的技术求助

解决批量下载PDF时的Permission Denied错误

我看了你这段批量下载NERC网站PDF的代码,遇到的IOError: [Errno 13] Permission denied: u'/trademark policy'问题其实很好定位——问题出在你直接用链接的文本作为文件名保存

错误原因分析

当你用l.text作为文件名时,遇到了像/trademark policy这样的文本,其中的/在操作系统里是路径分隔符。系统会误以为你要在根目录(比如Unix的/或者Windows的C:/)创建名为trademark policy的文件,但普通用户根本没有根目录的写入权限,所以直接触发了权限拒绝错误。另外还有个隐藏问题:你用"w"模式写入PDF文件,这是文本模式,而PDF是二进制文件,这样写出来的文件大概率会损坏打不开。

修复方案

我们需要做两个关键修改:清理文件名里的非法字符,改用二进制模式写入文件。下面是修改后的完整代码和细节说明:

import mechanize
from time import sleep

br = mechanize.Browser()
br.open('http://www.nerc.com/comm/CCC/Pages/AgendasHighlightsandMinutes-.aspx')
f = open("source.html", "w")
f.write(br.response().read())
filetypes = [".pdf"]
myfiles = []

for l in br.links():
    for t in filetypes:
        if t in str(l):
            myfiles.append(l)

def downloadlink(l):
    # 清理文件名中的非法字符:替换路径分隔符和其他不允许的字符为下划线
    safe_filename = l.text.replace('/', '_').replace('\\', '_').replace(':', '_').replace('?', '_').replace('"', '_').replace('<', '_').replace('>', '_')
    # 处理空文件名的情况,避免创建无效文件
    if not safe_filename.strip():
        safe_filename = f"unnamed_pdf_{hash(l.url)}.pdf"
    # 确保文件名以.pdf结尾,防止有些链接文本不带后缀
    if not safe_filename.lower().endswith('.pdf'):
        safe_filename += '.pdf'
    
    # 用二进制模式写入PDF文件,避免文件损坏
    with open(safe_filename, 'wb') as f:
        br.click_link(l)
        f.write(br.response().read())
    print(f"{safe_filename} 已成功下载")

for l in myfiles:
    sleep(1)
    downloadlink(l)

关键修改点说明

  • 清理非法字符:把/\:这些操作系统不允许出现在文件名里的字符全部替换成下划线,确保系统把它当成普通文件名而非路径。
  • 二进制写入:用wb模式打开文件,这是保存二进制文件(比如PDF、图片)的正确方式,能避免文件内容损坏。
  • 健壮性处理:添加了空文件名判断和自动补全.pdf后缀的逻辑,避免因为链接文本异常导致的下载失败。

这样修改后,不仅能解决权限拒绝的问题,还能保证下载的PDF文件正常可用。

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

火山引擎 最新活动