0

我必须下载一些文件。我在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 的文件,这显然不是下载的文件。

4

3 回答 3

2

该错误会告诉您究竟出了什么问题。您无权写入 path D:/Thesis/test_http_dl

有四个可能的原因:

  1. 您已经有一个具有该名称的文件,但您没有写入权限。
  2. 您无权在D:\Thesis.
  3. 您根本没有对 D: 驱动器的写访问权(例如,因为它是 CD-ROM)。
  4. 其他一些进程将文件打开以进行独占访问。

您需要查看 ACLD:\Thesis\test_http_dl是否存在或D:\Thesis\其他情况,并查看您的用户(您运行脚本的用户)是否具有写入权限,并检查该路径或 D 驱动器本身是否具有“只读”标志,并检查是否有任何其他进程打开了文件。(我不知道最后一个的任何内置工具,但handleProcess Explorer来自sysinternals可以轻松地为您完成。)

同时,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)or开始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,这可能是一个校验和文件——一种包含元数据的准标准类型的文件,可帮助您确保您正在下载的文件在传输过程中没有被损坏或被黑客篡改。典型的校验和文件有一行或多行,每一行将可下载文件映射到可下载文件的某种格式的校验和或加密哈希摘要。有时它们有三列——校验和/哈希的类型、某种字符串化格式的校验和/哈希的值,以及文件的文件名或完整 URL。有时第一列被省略,您必须从其他地方知道正在使用哪种类型的校验和/哈希(通常 MD5 作为十六进制字符串)。有时列的顺序不同。有时它们用逗号或制表符分隔,或者在固定宽度的字段中,或者其他一些变体中。

无论如何,您希望 .sum 文件的长度约为 80 字节。如果您在资源管理器或dir命令中查看它,它通常会四舍五入到最接近的 1K。因此,如果您成功下载,您应该会看到一个 1K 文件。

同时:

print(repr(ul[:60])) 是 '\n

你应该试着打印出剩下的部分,因为它可能是某种文件,用人类的语言解释你做错了什么。这可能是因为您需要传递 URL 代理、首选编码、引用者或其他一些标头。

但是,我测试了您重复使用的完全相同的代码行,并且ul始终是:

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

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

于 2012-12-20T00:27:16.627 回答
0

我已经尝试过你的代码并得到了同样的错误

所以试试这个: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')

适合我!

于 2012-12-20T00:34:37.897 回答
0
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') 
于 2012-12-20T13:55:43.553 回答