我想在Python中下载,提取和迭代文本文件,而无需创建临时文件。
基本上,这个管道,但在python中curl ftp://ftp.theseed.org/genomes/SEED/SEED.fasta.gz | gunzip | processing step
这是我的代码:
def main():
import urllib
import gzip
# Download SEED database
print 'Downloading SEED Database'
handle = urllib.urlopen('ftp://ftp.theseed.org/genomes/SEED/SEED.fasta.gz')
with open('SEED.fasta.gz', 'wb') as out:
while True:
data = handle.read(1024)
if len(data) == 0: break
out.write(data)
# Extract SEED database
handle = gzip.open('SEED.fasta.gz')
with open('SEED.fasta', 'w') as out:
for line in handle:
out.write(line)
# Filter SEED database
pass
我不想使用process.Popen()或其他任何东西,因为我希望这个脚本与平台无关。
问题是Gzip库只接受文件名作为参数而不是句柄。 “管道”的原因是下载步骤只占用了大约5%的CPU,同时运行提取和处理会更快。
修改: 这不起作用,因为
“因为gzip压缩的方式 有效,GzipFile需要保存它 位置和前进和前进 向后翻阅压缩文件。 当“文件”是a时,这不起作用 来自远程的字节流 服务器;你所能做的就是 一次检索一个字节,而不是移动 通过数据来回传递 流。“ - dive into python
这就是我收到错误的原因
AttributeError: addinfourl instance has no attribute 'tell'
那么curl url | gunzip | whatever
如何运作?
答案 0 :(得分:9)
只是gzip.GzipFile(fileobj=handle)
你将会在路上 - 换句话说,“Gzip库只接受文件名作为参数而不是句柄”并不是真的,你只需要使用{{ 1}}命名参数。
答案 1 :(得分:0)
我在搜索从URL下载gzip
文件和解压缩文件的方法时发现了这个问题,但是我没有设法使可接受的答案在Python 2.7中起作用。
以下是对我有用的内容(改编自here):
import urllib2
import gzip
import StringIO
def download(url):
# Download SEED database
out_file_path = url.split("/")[-1][:-3]
print('Downloading SEED Database from: {}'.format(url))
response = urllib2.urlopen(url)
compressed_file = StringIO.StringIO(response.read())
decompressed_file = gzip.GzipFile(fileobj=compressed_file)
# Extract SEED database
with open(out_file_path, 'w') as outfile:
outfile.write(decompressed_file.read())
# Filter SEED database
# ...
return
if __name__ == "__main__":
download("ftp://ftp.ebi.ac.uk/pub/databases/Rfam/12.0/fasta_files/RF00001.fa.gz")
由于原始URL已死,所以我更改了目标URL:我只是从ftp服务器中寻找了一个gzip
文件,就像原始问题一样。
答案 2 :(得分:0)
一种python3
解决方案,它不需要,不需要for
循环并直接将byte
对象写为binary
流:
import gzip
import urllib.request
def download_file(url):
out_file = '/path/to/file'
# Download archive
try:
# Read the file inside the .gz archive located at url
with urllib.request.urlopen(url) as response:
with gzip.GzipFile(fileobj=response) as uncompressed:
file_content = uncompressed.read()
# write to file in binary mode 'wb'
with open(out_file, 'wb') as f:
f.write(file_content)
return 0
except Exception as e:
print(e)
return 1
使用retval=download_file(url)
调用函数以捕获return code
答案 3 :(得分:0)
对于python 3.8,这是我的代码,写于08/05/2020
import re
from urllib import request
import gzip
import shutil
url1 = "https://www.destinationlighting.com/feed/sitemap_items1.xml.gz"
file_name1 = re.split(pattern='/', string=url1)[-1]
r1 = request.urlretrieve(url=url1, filename=file_name1)
txt1 = re.split(pattern=r'\.', string=file_name1)[0] + ".txt"
with gzip.open(file_name1, 'rb') as f_in:
with open(txt1, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)