Requests.get(zipfile) 获取“BadZipFile:文件不是 zip 文件”

Posted

技术标签:

【中文标题】Requests.get(zipfile) 获取“BadZipFile:文件不是 zip 文件”【英文标题】:Requests.get(zipfile) gets 'BadZipFile: File is not a zip file" 【发布时间】:2019-04-07 00:39:21 【问题描述】:

我正在尝试加载位于一组地理文件的 zipfile 中的 shapefile。我尝试了几种方法并且一直在学习,但一无所获。以下代码应该适用于 Python 3.5。

我尝试了 Andrew Gaidus 示例方法,并意识到它适用于以前的 Python 版本。 Oldja 方法来自 Python 3.x 文档,应该可以使用。但问题不断出现。

dls = "https://github.com/ItsMeLarry/Coursera_Capstone/raw/master/tl_2010_25 009_tract00.zip"
print('Downloading shapefile...')
r = requests.get(dls)
z = zipfile.ZipFile(io.BytesIO(r.content))
print("Done")
z.extractall(path='tmp/') # extract to folder
filenames = [y for y in sorted(z.namelist()) for ending in ['dbf', 
'prj', 'shp', 'shx'] if y.endswith(ending)] 
print(filenames)
dbf, prj, shp, shx = [filename for filename in filenames]
print(shp)
lynnmap = gpd.read_file(shp)

我应该得到 4 个文件名。现在,在 lynnmap=gpd...,我得到了错误:

OSError:没有这样的文件或目录:'tl_2010_25009_tract00.shp'。

示例不执行“打开”操作,但我想知道 geopandas 是否告诉我应该这样做。

【问题讨论】:

那是因为响应是 404 Not Found(检查r.status_code)。您确定您的网址正确吗? @t.m.adam 你是对的。我忘记了我需要使用“原始”目录进行下载,而不是“blob”。当然,这只是将我引向下一个谜团。为此编辑了问题陈述。谢谢, 我认为shp 只是文件名,所以gpd.read_file() 找不到文件,因为它是在tmp/ 中提取的。您应该使用绝对或相对文件路径,例如tmp/tl_2010_25009_tract00.shp t.m.adam 好的,所以将“tmp/”附加到所有文件名。我会看看会发生什么。我想知道如果我不将它解压缩到 tmp 文件夹会发生什么。我会明白的。 MACOSX 和 Jupyter notebook 在文件管理方面存在争议。磁盘的行为就好像它已经被 Jupyter 和操作系统在不同的一侧进行了分区一样。 我对 Jupyter 或 MAC 没有太多经验,所以对此我无能为力。一般最好使用文件的绝对路径,这样即使不在脚本执行的同一路径下也能定位到。 【参考方案1】:

如果目标只是从 GitHub 读取文件并从中创建一个 GeoDataFrame(并且您不一定想在本地下载并解压缩它,以便更快地重新读取),您可以直接从使用geopandas.read_file函数的GitHub url:

In [4]: df = geopandas.read_file("https://github.com/ItsMeLarry/Coursera_Capstone/raw/master/tl_2010_25009_tract00.zip") 

In [5]: df.head()                                                      
Out[5]: 
  STATEFP00 COUNTYFP00  ...    INTPTLON00                                           geometry
0        25        009  ...  -070.9744124  POLYGON ((-70.977153 42.452525, -70.9773139999...
1        25        009  ...  -070.9789107  POLYGON ((-70.986276 42.46005299999999, -70.98...
2        25        009  ...  -070.9853846  POLYGON ((-70.988809 42.460175, -70.9889149999...
3        25        009  ...  -070.9611517  POLYGON ((-70.95187 42.473647, -70.950974 42.4...
4        25        009  ...  -070.9925246  (POLYGON ((-71.000474 42.507547, -70.999544 42...

[5 rows x 13 columns]

geopandas.read_file接受url,也可以自动处理不同shapefile文件的zip文件,并返回一个GeoDataFrame。

【讨论】:

t.m.adam 的建议效果很好。我终于很高兴了。还有很多事情要做。您是说,使用 geopandas,我可以直接从 URL 执行 gpd.read_file 而无需解压缩?我需要使用 shapefile 制作地图,并使用 prj 文件作为创建地理数据框的参考。如果没有明确的解压缩步骤,这一切是如何发生的? @t.m.dama,它按预期工作!谢谢。绘制地图并制作 geopandas df 以显示数据。感觉自己又向前迈进了很好。 geopandas.read_file 函数会为您解压缩(并加载所有不同的文件,包括 prj 文件)。 目标是创建一个 geopandas 数据框。我在继续时只显示部分代码。您似乎是在说 gpd.read_file 直接创建数据框。这意味着从 prj 和所有内容中添加参考信息。我的理解是否正确?谢谢。 是的,这就是geopandas.read_file 函数的目的:从一个文件或一组文件(在本例中为压缩文件)创建一个 GeoDataFrame。因此,对于 Shapefile(或 shp、prj、dbf 等文件的 zip),它会为您处理不同的文件(读取几何图形和属性以及投影信息)。

以上是关于Requests.get(zipfile) 获取“BadZipFile:文件不是 zip 文件”的主要内容,如果未能解决你的问题,请参考以下文章

使用 requests.get 或 webdriver.get 时无法获取所有 HTML

Python:BadZipFile:目录和标题中的文件名不同

requests从api中获取数据并存放到mysql中

使用requests模块进行初步爬虫

在Python中用requests.get()获取到的内容是啥类型的?

requests不带参数的get请求和带get参数请求