Python:像浏览器一样通过代理访问FTP

4 投票
1 回答
1779 浏览
提问于 2025-04-18 16:23

我想访问一个FTP服务器,匿名登录,只是为了下载文件。我的公司有一个代理服务器,而且FTP的端口(21)被封锁了,所以我不能直接访问这个FTP服务器。

我想做的是写一些代码,让它的行为和浏览器完全一样。我的想法是,如果我能通过浏览器下载文件,那就一定可以用代码实现。

我的代码在访问公司外部的网站时能正常工作,但对于FTP服务器仍然不行。

proxy = urllib2.ProxyHandler({'https': 'proxy.mycompanhy.com:8080',
                              'http': 'proxy.mycompanhy.com:80',
                              'ftp': 'proxy.mycompanhy.com:21' })
auth = urllib2.HTTPBasicAuthHandler()
opener = urllib2.build_opener(proxy, auth, urllib2.HTTPHandler)
urllib2.install_opener(opener)

urlAddress = 'https://python.org'
# urlAddress = 'ftp://ftp1.cptec.inpe.br'

conn = urllib2.urlopen(urlAddress)
return_str = conn.read()
print return_str    

当我尝试访问python.org时,一切正常。如果我去掉install_opener这一部分,就不行了,这证明代理是必须的。使用FTP网址时,它会被阻止(或者如果我选择使用这些参数,就会超时)。

我明白FTP和HTTP是两种非常不同的协议。 我不明白的是浏览器是如何访问这些FTP服务器的。我是说,我不知道服务器端是否有一个层在HTTP和FTP之间进行交互,获取HTML;或者浏览器以其他方式访问FTP并构建页面。

可能还有一个关于FTP域名(或网址)和连接模式的混淆。对我来说,当urllib2读取ftp://...时,它似乎自动使用了21端口。

1 个回答

2

我找到了一种用wget的解决办法。这个工具可以处理代理,但它的说明文档写得很模糊。你需要设置一个环境变量,里面放上代理的名称。

import wget
import os
import errno

# setup proxy
os.environ["ftp_proxy"] = "proxy.mycompanhy.com"
os.environ["http_proxy"] = "proxy.mycompanhy.com"
os.environ["https_proxy"] = "proxy.mycompanhy.com"

src = "http://domain.gov/data/fileToDownload.txt"
out = "C:\\outFolder\\outFileName.txt" # out is optional

# create output folder if it doesn't exists
outFolder, _ = os.path.split( out )
try:
    os.makedirs(outFolder)
except OSError as exc: # Python >2.5
    if exc.errno == errno.EEXIST and os.path.isdir(outFolder):
        pass
    else: raise

# download
filename = wget.download(src, out)

撰写回答