使用Python下载文件

btxsgosb  于 2023-02-11  发布在  Python
关注(0)|答案(4)|浏览(217)

我必须下载一些文件。我在python中尝试了下面的代码。

import urllib2
ul = urllib2.urlopen('http://dds.cr.usgs.gov/emodis/Africa/historical/TERRA/2012/comp_056/AF_eMTH_NDVI.2012.047-056.QKM.COMPRES.005.2012059143841.zip.sum').read()
open("D:/Thesis/test_http_dl", "w").write(ul)

它会抛出以下错误:

IOError: [Errno 13] Permission denied: 'D:/Thesis/test_http_dl'

你知道为什么吗?我做错什么了吗?
我试过不同的文件夹,但都不起作用。我的文件夹不是只读的。print(repr(ul[:60]))的结果是'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n<htm'
urllib.urlretrieve()只是在文件夹中创建了一个1 kb的文件,显然不是下载的文件。

pkln4tw6

pkln4tw61#

这个错误告诉你到底哪里出错了。你没有写路径D:/Thesis/test_http_dl的权限。
这可能有四个原因:
1.您已经有一个具有该名称的文件,但您没有该文件的写入权限。
1.您没有在D:\Thesis中创建新文件的权限。
1.您没有对D:驱动器(例如,因为它是CD-ROM)。
1.其他某个进程以独占访问方式打开了该文件。
您需要查看D:\Thesis\test_http_dl(如果存在)或D:\Thesis\(如果不存在)的ACL,并查看您的用户(您运行脚本的身份)具有写访问权限,还要检查该路径或D驱动器本身是否打开了"只读"标志,还要检查是否有任何其他进程打开了该文件。(我不知道有没有内置工具可以完成最后一个任务,但是sysinternals中的handleProcess Explorer可以很容易地完成这个任务。)
与此同时,与urllib2相关的内容在这里都不相关,您可以通过执行以下操作来验证:

open("D:/Thesis/test_http_dl", "w")

您将得到完全相同的异常。
如果异常没有告诉你到底出了什么问题,那么知道如何用"困难"的方法来解决这个问题是值得的。

open("D:/Thesis/test_http_dl", "w").write(ul)

如果你没有足够的信息来判断错误是什么,你会怎么做呢?首先,把它分成几个部分,这样每一行都有一个操作:

f = open("D:/Thesis/test_http_dl", "w")
f.write(ul)

现在你知道这两个中的哪一个会得到异常了。
既然这段代码唯一依赖的是ul,那么可以创建一个更简单的程序来测试它:

ul = 'junk'
f = open("D:/Thesis/test_http_dl", "w")
f.write(ul)

即使这对您没有直接帮助,但这意味着您不必每次在测试循环中都等待下载,并且您可以将一些更简单的内容发布到SO(更多信息请参见SSCCE),您只需在交互式解释器中键入这些内容,而不必试图猜测打印出哪些内容可能对查看write引发异常的原因有用,您可以从help(f)dir(f)开始,然后现场使用它(在本例中,我猜实际上是open失败了,而不是write,但您不应该猜测)。
关于第二个问题:
urllib. urlretrieve()只是在文件夹中创建一个1 KB的文件,显然不是下载的文件。
实际上,我认为它是下载的文件。你不是在请求AF_eMTH_NDVI.2012.047-056.QKM.COMPRES.005.2012059143841.zip,你是在请求AF_eMTH_NDVI.2012.047-056.QKM.COMPRES.005.2012059143841.zip.sum,这可能是一个校验和文件--一个准标准类型的文件,包含元数据,帮助你确保你下载的文件没有在传输过程中损坏或被黑客篡改。一个典型的校验和文件有一行或多行,每一个将可下载文件Map到可下载文件的某种格式的校验和或加密散列摘要。有时它们具有三列-校验和/散列的类型、某种字符串化格式的校验和/散列的值以及文件的文件名或完整URL。有时省略第一列,而且你必须从别处知道使用的校验和/散列的类型(通常MD5是十六进制字符串)。有时候列的顺序不同。有时候它们用逗号或制表符分隔,或者在固定宽度的字段中,或者其他一些变化。
无论如何,你会期望一个. sum文件大约80字节长。如果你在资源管理器或dir命令中查看它,它通常会被四舍五入到最近的1K。所以,如果你成功下载了这个文件,你应该会看到一个1K的文件。
同时:
打印(repr(ul [:60]))为"\n
你应该试着把剩下的打印出来,因为它可能是某种文档,用人类的语言解释你做错了什么,这可能是因为你需要传递一个URL代理、一个首选编码、一个引用者或其他一些头。
但是,我测试了您反复使用的完全相同的代码行,ul始终为:

1ba6437044bfa9259fa2d3da8f95aebd  AF_eMTH_NDVI.2012.047-056.QKM.COMPRES.005.2012059143841.zip

换句话说,它是一个完全有效的校验和文件,而不是一个HTML页面。所以,我怀疑真正发生的事情是,您没有测试您向我们展示的相同代码。

fd3cxomn

fd3cxomn2#

我已经尝试你的代码和得到同样的错误
所以试试这个:D

import urllib
urllib.urlretrieve('http://dds.cr.usgs.gov/emodis/Africa/historical/TERRA/2012/comp_056/AF_eMTH_NDVI.2012.047-056.QKM.COMPRES.005.2012059143841.zip.sum','C:\\path_of_your_folder\\xx.zip.sum')

对我来说很好!

rpppsulh

rpppsulh3#

import urllib2
def download(url, file):
    dataset = urllib2.urlopen(url)
    CHUNK = 16 * 1024
    with open(file, 'wb') as dl:
        while True:
            peice = dataset.read(CHUNK)
            if not peice: break
            dl.write(peice)

download(r'http://dds.cr.usgs.gov/emodis/Africa/historical/TERRA/2012/comp_056/AF_eMTH_NDVI.2012.047-056.QKM.COMPRES.005.2012059143841.zip',r'AF_eMTH_NDVI.2012.047-056.QKM.COMPRES.005.2012059143841.zip')
ddrv8njm

ddrv8njm4#

def download_file(url):
    local_filename = url.split('/')[-1]
    # NOTE the stream=True parameter below
    with requests.get(url, stream=True) as r:
        r.raise_for_status()
        with open(local_filename, 'wb') as f:
            for chunk in r.iter_content(chunk_size=8192): 
                # If you have chunk encoded response uncomment if
                # and set chunk_size parameter to None.
                #if chunk: 
                f.write(chunk)
    return local_filename

相关问题