ディスクに何も保存できない環境で作業しています。ディスクに保存せずにtarファイルをプルして解凍できるようにする必要があります。これは失敗するようです:
私はこれを試しましたが、エラーが発生します:
# fetch.py
from cStringIO import StringIO
import requests
url = "http://example.com/data.tar.gz"
response = requests.get(url)
# ERROR is thrown here. Error shown below
tar = tarfile.open(mode= "r:gz", fileobj = StringIO(response.content))
# This SHOULD break as tar.extract() saves to disk.
# Can't tell because of error on previous line of code.
data = tar.extract()
上記のコードブロックで説明されているように、エラー行に次のトレースバックが表示されます。
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "./importers/bestbuy_fetcher.py", line 23, in download_bestbuy_batch
tar = tarfile.open(mode= "r:gz", fileobj = StringIO(response.content))
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/tarfile.py", line 1662, in open
return func(name, filemode, fileobj, **kwargs)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/tarfile.py", line 1711, in gzopen
**kwargs)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/tarfile.py", line 1689, in taropen
return cls(name, mode, fileobj, **kwargs)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/tarfile.py", line 1568, in __init__
self.firstmember = self.next()
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/tarfile.py", line 2324, in next
raise ReadError(str(e))
ReadError: invalid header
問題は、ファイル "data.tar.gzがtarアーカイブではなかったということでした。gzip圧縮ファイルだけでした。それで私はそれを次のように解決しました:
# fetch.py
from cStringIO import StringIO
import gzip
import requests
# Called a 'tar' file but actually a gzip file. @#$%!!!
url = "http://example.com/data.tar.gz"
response = requests.get(url)
results = gzip.GzipFile(fileobj=StringIO(response.content))
ピッチインを手伝ってくれたみんなに感謝します!
エラーは、tarfileのファイル形式が間違っていることを示していると思われます。 wget
を使用してファイルをフェッチし、コマンドラインで解凍してみてください。
Pythonファイルの内容をディスクに書き込むのを停止する方法についてのもう1つの質問は、tarfile
APIを詳しく調べる必要があります。TarFile.extract()
を呼び出す代わりにtarファイル内のすべてのメンバーの名前を返すgetnames()
が必要です。次に、extractfile
を使用してそのメンバーの内容を取得できます。
| extractfile(self, member)
| Extract a member from the archive as a file object. `member' may be
| a filename or a TarInfo object. If `member' is a regular file, a
| file-like object is returned. If `member' is a link, a file-like
| object is constructed from the link's target. If `member' is none of
| the above, None is returned.
| The file-like object is read-only and provides the following
| methods: read(), readline(), readlines(), seek() and tell()
次に例を示します。
import tarfile
# Open tarfile
tar = tarfile.open(mode="r:gz", fileobj = file('foo.tgz'))
# Iterate over every member
for member in tar.getnames():
# Print contents of every file
print tar.extractfile(member).read()
Request + tarを処理するときに行ったことを試すことができます。ファイルを開くモード。詳細については、 http://docs.python.org/library/tarfile.html#tarfile.open を参照してください。
コードは https://github.com/djeese/djeese-client/blob/master/djeese/commands/clonestatic.py#L5 で確認できます。
基本的には、tarfile.open(mode='r|gz', fileobj=response.raw)
を使用してtarファイルを開きます。
それは私たちにとって素晴らしくうまくいきました、そしてうまくいけばあなたにもうまくいきます。
これは役立つはずです
import sys
import zipfile
sys.argv[0] = "/home/tom/Documents/REdata/AllListing1RES.Zip"
Zip_file = zipfile.ZipFile(sys.argv[0])
items_file = Zip_file.open('AllListing1RES.txt', 'rU')
df = read_table(items_file, sep='\t', index_col=0)