Прогресс для загрузки больших файлов CSV из Интернета с использованием Python

Я читаю книгу анализа данных Маккинни, и он поделился файлом 150 МБ. Хотя этот вопрос широко обсуждался на панели выполнения, загружая файл через http с помощью запросов , я обнаружил, что код в принятом ответе вызывает ошибку. Я новичок, поэтому я не могу это решить.

Я хочу загрузить следующий файл:

https://raw.githubusercontent.com/wesm/pydata-book/2nd-edition/datasets/fec/P00000001-ALL.csv

Вот код без индикатора выполнения:

DATA_PATH='./Data'
filename = "P00000001-ALL.csv"
url_without_filename = "https://raw.githubusercontent.com/wesm/pydata-book/2nd-edition/datasets/fec"

url_with_filename = url_without_filename + "/" + filename
local_filename = DATA_PATH + '/' + filename

#Write the file on local disk
r = requests.get(url_with_filename)  #without streaming
with open(local_filename, 'w', encoding=r.encoding) as f:
    f.write(r.text)

Это работает хорошо, но поскольку нет индикатора прогресса, мне интересно, что происходит.

Вот код, адаптированный из панели выполнения, в то время как файл загрузки через http с запросами и как загрузить большой файл в python с request.py?

#Option 2:
#Write the file on local disk
r = requests.get(url_with_filename, stream=True)  # added stream parameter
total_size = int(r.headers.get('content-length', 0))

with open(local_filename, 'w', encoding=r.encoding) as f:
    #f.write(r.text)
    for chunk in tqdm(r.iter_content(1024), total=total_size, unit='B', unit_scale=True):
        if chunk:
            f.write(chunk)

Есть две проблемы со вторым вариантом (т. tqdm С потоковой передачей и пакетом tqdm ):

a) Размер файла вычисляется неправильно. Фактический размер составляет 157 МБ, но total_size оказывается равным 25 МБ.

б) Еще большая проблема, чем а) ​​заключается в том, что я получаю следующую ошибку:

 0%|          | 0.00/24.6M [00:00<?, ?B/s] Traceback (most recent call last):   File "C:Anaconda3libsite-packagesIPythoncoreinteractiveshell.py", line 3265, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)   File "<ipython-input-31-abbe9270092b>", line 6, in <module>
    f.write(data) TypeError: write() argument must be str, not bytes

Как новичок, я не уверен, как решить эти два вопроса. Я потратил много времени на git-страницу tqdm , но я не мог следовать за ней. Буду признателен за любую помощь.


Я предполагаю, что читатели знают, что нам нужно импортировать requests и tqdm . Итак, я не включил код для импорта этих базовых пакетов.


Вот код для любопытных:

with open(local_filename, 'wb') as f:
    r = requests.get(url_with_filename, stream=True)  # added stream parameter
    # total_size = int(r.headers.get('content-length', 0))
    local_filename = DATA_PATH + '/' + filename
    total_size = len(r.content)
    downloaded = 0
    # chunk_size = max(1024*1024,int(total_size/1000))
    chunk_size = 1024
    #for chunk in tqdm(r.iter_content(chunk_size=chunk_size),total=total_size,unit='KB',unit_scale=True):
    for chunk in r.iter_content(chunk_size=chunk_size):
        downloaded += len(chunk)
        a=f.write(chunk)
        done = int(50 * downloaded/ total_size)
        sys.stdout.write("
[%s%s]" % ('=' * done, ' ' * (50 - done)))
        sys.stdout.flush()

Всего 3 ответа

Автоматический диспенсер мыльной пены от xiaomi.


with open(filename, 'wb', encoding=r.encoding) as f:
    f.write(r.content)

Это должно исправить вашу проблему с письмом. Write r.content not r.text Так как type(r.content) - это <class 'bytes'> то, что вам нужно записать в файл


Как говорится в ошибке:

write () должен быть str, а не байтами

поэтому просто конвертируйте кусок в строку :

f.write(str(chunk))

Примечание. Вместо этого я бы предложил записать в .bin- файл, а затем преобразовать его в .csv


Попробуйте написать с помощью wb вместо w .

with open( local_filename, 'wb', encoding= r.encoding ) as f:
    f.write( r.text )

Есть идеи?

10000