简体   繁体   English

如何从 ftp 下载文件?

[英]How to download file from ftp?

I'm scripting an install script in python.我正在编写 python 中的安装脚本。

How do I download file from ftp in python?如何从 python 中的 ftp 下载文件?

Operating system -- Windows XP - if that makes a difference.操作系统——Windows XP——如果有区别的话。

from urllib2 import urlopen
req = urlopen('ftp://ftp.gnu.org/README')

Then you can use req.read() to load the file content into a variable or do anything else with it, or shutil.copyfileobj to save the content to a disk without loading it to memory.然后,您可以使用req.read()将文件内容加载到变量中或对其执行任何其他操作,或者shutil.copyfileobj将内容保存到磁盘而不将其加载到 memory。

Here's a code snippet I'm currently using.这是我目前正在使用的代码片段。

import mimetypes
import os
import urllib2
import urlparse

def filename_from_url(url):
    return os.path.basename(urlparse.urlsplit(url)[2])

def download_file(url):
    """Create an urllib2 request and return the request plus some useful info"""
    name = filename_from_url(url)
    r = urllib2.urlopen(urllib2.Request(url))
    info = r.info()
    if 'Content-Disposition' in info:
        # If the response has Content-Disposition, we take filename from it
        name = info['Content-Disposition'].split('filename=')[1]
        if name[0] == '"' or name[0] == "'":
            name = name[1:-1]
    elif r.geturl() != url:
        # if we were redirected, take the filename from the final url
        name = filename_from_url(r.geturl())
    content_type = None
    if 'Content-Type' in info:
        content_type = info['Content-Type'].split(';')[0]
    # Try to guess missing info
    if not name and not content_type:
        name = 'unknown'
    elif not name:
        name = 'unknown' + mimetypes.guess_extension(content_type) or ''
    elif not content_type:
        content_type = mimetypes.guess_type(name)[0]
    return r, name, content_type

Usage:用法:

req, filename, content_type = download_file('http://some.url')

Then you can use req as a file-like object and eg use shutil.copyfileobj() to copy the file contents into a local file.然后您可以将req用作类似 object 的文件,例如使用shutil.copyfileobj()将文件内容复制到本地文件中。 If the MIME type doesn't matter simply remove that part of the code.如果 MIME 类型无关紧要,只需删除该部分代码即可。

Since you seem to be lazy, here's code downloading the file directly to a local file:由于您似乎很懒惰,因此将文件直接下载到本地文件的代码如下:

import shutil
def download_file_locally(url, dest):
    req, filename, content_type = download_file(url)        
    if dest.endswith('/'):
        dest = os.path.join(dest, filename)
    with open(dest, 'wb') as f:
        shutil.copyfileobj(req, f)
    req.close()

This method is smart enough to use the filename sent by the server if you specify a path ending with a slash, otherwise it uses the destination you specified.如果您指定以斜杠结尾的路径,则此方法非常聪明,可以使用服务器发送的文件名,否则它使用您指定的目标。

Use ftplib使用ftplib

Code Sample from the documentation:文档中的代码示例:

>>> from ftplib import FTP
>>> ftp = FTP('ftp.cwi.nl')   # connect to host, default port
>>> ftp.login()               # user anonymous, passwd anonymous@
>>> ftp.retrlines('LIST')     # list directory contents
total 24418
drwxrwsr-x   5 ftp-usr  pdmaint     1536 Mar 20 09:48 .
dr-xr-srwt 105 ftp-usr  pdmaint     1536 Mar 21 14:32 ..
-rw-r--r--   1 ftp-usr  pdmaint     5305 Mar 20 09:48 INDEX
 .
 .
 .
>>> ftp.retrbinary('RETR README', open('README', 'wb').write)
'226 Transfer complete.'
>>> ftp.quit()
from urllib.request import urlopen
try:
    req = urlopen('ftp://ftp.expasy.org/databases/enzyme/enzclass.txt')
except:
    print ("Error")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM