如何从ftp下载文件?

发布于 2024-11-28 22:49:22 字数 90 浏览 0 评论 0原文

我正在用 python 编写安装脚本。

如何在Python中从ftp下载文件?

操作系统——Windows XP——如果这有影响的话。

I'm scripting an install script in python.

How do I download file from ftp in python?

Operating system -- Windows XP - if that makes a difference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

靑春怀旧 2024-12-05 22:49:22
from urllib2 import urlopen
req = urlopen('ftp://ftp.gnu.org/README')

然后,您可以使用 req.read() 将文件内容加载到变量中或对其执行任何其他操作,或者使用 shutil.copyfileobj 将内容保存到磁盘,而无需将其加载到内存中。

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.

鹤仙姿 2024-12-05 22:49:22

这是我当前正在使用的代码片段。

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

用法:

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

然后您可以使用 req 作为类似文件的对象,例如使用 shutil.copyfileobj() 将文件内容复制到本地文件中。如果 MIME 类型无关紧要,只需删除该部分代码即可。

由于您似乎很懒,所以这里是直接将文件下载到本地文件的代码:

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()

如果您指定以斜杠结尾的路径,此方法足够聪明,可以使用服务器发送的文件名,否则它使用您指定的目标。

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 e.g. use shutil.copyfileobj() to copy the file contents into a local file. If the MIME type doesn't matter simply remove that part of the code.

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.

做个少女永远怀春 2024-12-05 22:49:22

使用

文档中的 ftplib 代码示例:

>>> 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()

Use 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()
谁的年少不轻狂 2024-12-05 22:49:22
from urllib.request import urlopen
try:
    req = urlopen('ftp://ftp.expasy.org/databases/enzyme/enzclass.txt')
except:
    print ("Error")
from urllib.request import urlopen
try:
    req = urlopen('ftp://ftp.expasy.org/databases/enzyme/enzclass.txt')
except:
    print ("Error")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文