13

FTP サーバーからファイルを読み込もうとしています。ファイルは.gzファイルです。ソケットが開いている間にこのファイルに対してアクションを実行できるかどうかを知りたいです。ディスクに書き込まずにファイルを読み取ることと、ダウンロードせずに FTP からファイルを読み取ることに関する2つの StackOverflow の質問に記載されている内容に従おうとしましたが、成功しませんでした。

データを抽出する方法やダウンロードしたファイルで作業する方法は知っていますが、その場で実行できるかどうかはわかりません。サイトに接続し、バッファにデータを取得し、データを抽出して終了する方法はありますか?

StringIO を試すと、次のエラーが発生しました。

>>> from ftplib import FTP
>>> from StringIO import StringIO
>>> ftp = FTP('ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz')

Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
ftp = FTP('ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz')
File "C:\Python27\lib\ftplib.py", line 117, in __init__
self.connect(host)
File "C:\Python27\lib\ftplib.py", line 132, in connect
self.sock = socket.create_connection((self.host, self.port), self.timeout)
File "C:\Python27\lib\socket.py", line 553, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
gaierror: [Errno 11004] getaddrinfo failed

FTP からのファイルが読み取られるまで、変数にデータを取得してループする方法を知る必要があります。

お時間をいただき、ありがとうございます。ありがとう!

4

3 に答える 3

29

最初に必ず ftp サーバーにログインしてください。この後、retrbinarywhich を使用してファイルをバイナリモードでプルします。ファイルの各チャンクでコールバックを使用します。これを使用して文字列にロードできます。

from ftplib import FTP
ftp = FTP('ftp.ncbi.nlm.nih.gov')
ftp.login() # Username: anonymous password: anonymous@

# Setup a cheap way to catch the data (could use StringIO too)
data = []
def handle_binary(more_data):
    data.append(more_data)

resp = ftp.retrbinary("RETR pub/pmc/PMC-ids.csv.gz", callback=handle_binary)
data = "".join(data)

おまけ: 途中で文字列を解凍してみませんか?

上記のデータ文字列を使用した簡単モード

import gzip
import StringIO
zippy = gzip.GzipFile(fileobj=StringIO.StringIO(data))
uncompressed_data = zippy.read()

少し良い、完全な解決策

from ftplib import FTP
import gzip
import StringIO

ftp = FTP('ftp.ncbi.nlm.nih.gov')
ftp.login() # Username: anonymous password: anonymous@

sio = StringIO.StringIO()
def handle_binary(more_data):
    sio.write(more_data)

resp = ftp.retrbinary("RETR pub/pmc/PMC-ids.csv.gz", callback=handle_binary)
sio.seek(0) # Go back to the start
zippy = gzip.GzipFile(fileobj=sio)

uncompressed = zippy.read()

実際には、オンザフライで解凍する方がはるかに優れていますが、組み込みのライブラリでそれを行う方法はわかりません (少なくとも簡単ではありません)。

于 2013-09-12T20:07:31.037 に答える
6

FTP を使用してファイルをダウンロードし、ローカルに保存するには、次の 2 つの簡単な方法が考えられます。

  1. 使用ftplib:

    from ftplib import FTP
    
    ftp = FTP('ftp.ncbi.nlm.nih.gov')
    ftp.login()
    ftp.cwd('pub/pmc')
    ftp.retrbinary('RETR PMC-ids.csv.gz', open('PMC-ids.csv.gz', 'wb').write)
    ftp.quit()
    
  2. 使用するurllib

    from urllib import urlretrieve
    
    urlretrieve("ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz", "PMC-ids.csv.gz")
    

ダウンロードしてファイルに保存したくないが、徐々に処理したい場合は、次を使用することをお勧めしurllib2ます。

from urllib2 import urlopen

u = urlopen("ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/readme.txt")

for line in u:
   print line

ファイルを1行ずつ印刷します。

于 2013-09-12T19:37:22.943 に答える