2015-04-01 33 views
8

jestem pobierania skompresowany plik z internetu:Ściąganie dużych plików przez pomyłkę Pythona: Sprężone plik zakończony przed markerem end-of-Stream został osiągnięty

with lzma.open(urllib.request.urlopen(url)) as file: 
    for line in file: 
     ... 

Po pobraniu i przetworzeniu aa dużą część plik, w końcu pojawia się błąd:

File "/usr/lib/python3.4/lzma.py", line 225, in _fill_buffer raise EOFError("Compressed file ended before the " EOFError: Compressed file ended before the end-of-stream marker was reached

myślę, że może to być spowodowane przez internet, że krople lub serwer nie odpowiada za jakiś czas. Jeśli tak jest, to czy jest tak, aby kontynuować próbę, dopóki połączenie nie zostanie ponownie ustanowione, zamiast rzucać wyjątek. Nie sądzę, że jest to problem z plikiem, ponieważ ręcznie pobrałem wiele plików podobnych do tego z tej samej strony internetowej i rozpakowałem je. Mogłem także pobrać i rozpakować kilka mniejszych plików za pomocą Pythona. Plik, który próbuję pobrać, ma skompresowany rozmiar około 20 GB.

+0

Ile czasu zajmuje pobranie pliku, zanim pojawi się błąd? Niektóre ściany ogniowe/serwery proxy wydają się kończyć połączenia po określonym czasie oczekiwania (na przykład 10 minut). Jeśli zawsze kończy się niepowodzeniem po tym samym odstępie czasu, może to być wskazówka ... – DNA

+0

Możliwy duplikat [Python LZMA: skompresowane dane zakończone przed osiągnięciem znacznika końca strumienia] (http://stackoverflow.com/questions/37400583/python-lzma-compressed-data-ended-before-the-end-of-stream-marker-was-reach) – kenorb

+1

Mam ten sam problem podczas próby pracy z bardzo dużym plikiem w Internecie przy użyciu 'urllib .request.urlopen() 'i' gzip'. Około 12 godzin dostaję podobne ślady. – bmende

Odpowiedz

2

z urllib.urlopen docs:

One caveat: the read() method, if the size argument is omitted or negative, may not read until the end of the data stream; there is no good way to determine that the entire stream from a socket has been read in the general case.

Może lzma.open wyjazdy na ogromnych błędów rozmiar/gra/timeout powodu wyżej.

2

To prawdopodobnie błąd liblzma. Aby obejść ten problem, dodaj:

lzma._BUFFER_SIZE = 1023 

przed dzwonieniem pod numer lzma.open().

0

Zakładając, że musisz pobrać duży plik, lepiej jest użyć trybu "zapisu i binarnego" podczas zapisywania treści do pliku w pythonie.

Możesz także spróbować użyć modułu python requests ponad modułu urllib:

proszę zobaczyć poniżej kodu robocza:

import requests 
url="http://www.google.com" 
with open("myoutputfile.ext","wb") as f: 
    f.write(requests.get(url).content) 

można przetestować ten kawałek kodu i odpowiedzi z powrotem, jeśli nie robi nie rozwiązuje twojego problemu.

Pozdrawiam

2

Czy próbowałeś korzystać z biblioteki żądań? Wierzę, że zapewnia abstrakcję ponad urllib.

Poniższe rozwiązanie powinno działać, ale używa biblioteki żądań zamiast urllib (ale prośby> urllib mimo to!). Daj mi znać, jeśli wolisz nadal korzystać z urllib.

import os 
import requests 
def download(url, chunk_s=1024, fname=None): 
    if not fname: 
     fname = url.split('/')[-1] 
    req = requests.get(url, stream=True) 
    with open(fname, 'wb') as fh: 
     for chunk in req.iter_content(chunk_size=chunk_s): 
      if chunk: 
       fh.write(chunk) 
    return os.path.join(os.getcwd(), fname)