在Python中从URL下载文件

时间:2017-07-20 08:25:27

标签: python csv url download python-requests

我有一个包含67000行网址的CSV文件。每个URL都可以下载CSV,HWP,ZIP等格式的其他数据集。

这是我写的代码:

import cgi
import requests


SAVE_DIR = 'C:/dataset'

def downloadURLResource(url):
    r = requests.get(url.rstrip(), stream=True)
    if r.status_code == 200:
        targetFileName = requests.utils.unquote(cgi.parse_header(r.headers['content-disposition'])[1]['filename'])
        with open("{}/{}".format(SAVE_DIR, targetFileName), 'wb') as f:
            for chunk in r.iter_content(chunk_size=1024):
                f.write(chunk)
        return targetFileName


with open('C:/urlcsv.csv') as f:
    print(list(map(downloadURLResource, f.readlines())))

此代码正常工作,直到达到第203个网址。

当我检查shell时,此网址没有内容处理并导致错误。

此外,它下载了201和202但是当我检查SAVE_DIR时,共有200个文件,这意味着有2个文件丢失。

我的问题是:

(1)如果不手动检查下载文件和URL的名称,如何知道哪些文件未下载? (没有错误代码在Python Shell中显示,它只是跳过了)

(2)如何修复我的代码以打印尚未下载的文件或URL的名称? (两个跳过的文件没有停止+没有在shell上显示错误,一些停止并在shell上显示错误)

这是阻止我下载的错误:

Traceback (most recent call last):

  File "C:\Users\pc\Desktop\오목눈이\URL다운.py", line 38, in <module>

   print(list(map(downloadURLResource, f.readlines())))

  File "C:\Users\pc\Desktop\오목눈이\URL다운.py", line 30, in downloadURLResource
    targetFileName = requests.utils.unquote(cgi.parse_header(r.headers['content-disposition'])[1]['filename'])

  File "C:\Python34\lib\site-packages\requests\structures.py", line 54, in __getitem__

   return self._store[key.lower()][1]

KeyError: 'content-disposition'

网址http://www.data.go.kr/dataset/fileDownload.do?atchFileId=FILE_000000001210727&fileDetailSn=1&publicDataDetailPk=uddi:4cf4dc4c-e0e9-4aee-929e-b2a0431bf03e  没有内容处置标题

Traceback (most recent call last):

 File "C:\Users\pc\Desktop\오목눈이\URL다운.py", line 46, in <module>

  print(list(map(downloadURLResource, f.readlines())))

 File "C:\Users\pc\Desktop\오목눈이\URL다운.py", line 38, in downloadURLResource

  return targetFileName

UnboundLocalError: local variable 'targetFileName' referenced before assignment

1 个答案:

答案 0 :(得分:1)

您正在使用if r.status_code == 200:

过滤掉任何不是200响应的内容

你所做的确切取决于当文件不在时请求的响应,但假设它是404,你可以尝试类似

r = requests.get(url.rstrip(), stream=True)
    if r.status_code == 200:
        content_dispotistion = r.headers.get('content-disposition')
        if content_disposition is not None:
            targetFileName = requests.utils.unquote(cgi.parse_header(content_dispotistion)[1]['filename'])
            with open("{}/{}".format(SAVE_DIR, targetFileName), 'wb') as f:
                for chunk in r.iter_content(chunk_size=1024):
                    f.write(chunk)
            return targetFileName
        else:
            print('url {} had no content-disposition header'.format(url))
    elif r.status_code == 404:
        print('{} returned a 404, no file was downloaded'.format(url))
    else:
        print('something else went wrong with {}'.format(url))

您的问题不太可重复,因此其他人难以测试。请考虑添加一些导致问题出现问题的网址。