使用 Python 使用 FTP 设置代理



我们正在尝试开发一个Python模块,该模块将访问FTP服务器并将文件下载到我的本地机器。当我们尝试运行模块的FTP部分时,它会超时。

我们有一个代理服务器(我们称之为"officeproxy.com:8080"(来处理这个问题,当使用FileZilla或Windows资源管理器等FTP客户端访问FTP站点时,我们成功了。

让我们称 ftp 站点为"ftp.cal.com"。 用户名是"爸爸"。 密码是"tango123"。

到目前为止,我们有:

Proxy = officeproxy.com:8080
FTP = ftp.cal.com
User = papa
PW = tango123 

以上不是真实的实体,所以如果你想把它们换成真实的实体,请做我的客人。

我需要一个模块来首先加载代理服务,然后运行FTP部分。

我正在运行Python 2.7。

到目前为止,我已经搜索并拥有此代码。 OP表示,它只是一个简短的模块,用于测试与FTP的连接并读取一个文件。

(注:我故意把#放在很多地方,在不知道填写的时候显示,或者其他原因(:

import urllib2
# I have filled in the proxy info
proxy_host = 'officeproxy.com:8080'
# I don't think this needs any modification, right?  
proxy_handler = urllib2.ProxyHandler({'ftp': proxy_host})
# ditto here 
proxy_auth_handler = urllib2.ProxyBasicAuthHandler() 
# now here is where I am unsure what to put; 
# also, I really need FTP user and FTP password, and NOT Proxy... 
# so what do I need to change here?
proxy_auth_handler.add_password(None, proxy_host, proxy_user, proxy_passwd) 
opener_thru_proxy = urllib2.build_opener(proxy_handler, proxy_auth_handler)
# I filled in this part
conn = opener_thru_proxy.open('ftp://ftp.cal.com/hello.txt') 
# I don't believe I need to change this, right?
print conn.read()

添加此内容,因为它是最重要的结果之一,并且努力寻找解决方案。

如果您的代理是HTTP 代理,并且您需要对其进行身份验证,则方法如下:

import socks
import socket
socks.set_default_proxy(socks.HTTP, 
proxy_host, 
proxy_port, 
username=proxy_username, 
password=proxy_password
)
socket.socket = socks.socksocket
ftp = FTP(ftp_host)
ftp.set_debuglevel(1) 
ftp.login(
user=ftp_user,
passwd=ftp_password
)

否则,对于FTP代理,马丁的答案有效。您也可以在FileZilla中看到FTP代理的行为,这将有助于根据您的要求进行编码。

希望这对某人有所帮助!

请注意,我在 SO 上发现了一些类似的问题,但由于 OP 要求提供详细的初学者级答案,我决定发布这个。

澄清一下,以下是我对您想要完成的任务的理解:

  • 您在代理后面有一个 FTP 服务器。
  • FTP 服务器需要用户/密码凭据,但代理本身不需要。

一种选择是使用ftplib包。像Python这样的流行语言的一大优势是广泛的包选择,这些包提供了特定功能的良好实现。在本例中,ftp 客户端:

import ftplib  # 1
ftp = ftplib.FTP("officeproxy.com:8080")  # 2
ftp.set_debuglevel(1)  # 3
ftp.login("papa", "tango123")  # 4
filename = "hello.txt"
f = open(filename, 'wb')  # 5 
ftp.retrbinary("RETR " + filename , f.write)  # 6
f.close()   # cleanup file handle
ftp.quit()  # cleanup ftp client 

以下是代码正在执行的操作:

  1. 导入ftplib包。
  2. 通过代理连接到 FTP 服务器。我编写它的方式假设代理设置为在指定的端口(示例中为 8080(上转发 FTP 协议。如果不是这种情况,这将不起作用。
  3. 启用调试日志记录。从 ftplib 文档中:

FTP.set_debuglevel(level)0,不产生调试输出...1产生适量的调试输出...2或更高,可生成最大数量的调试输出

  1. 使用 user="papa", passwd="tango123" 登录到 FTP 服务器。同样,这是来自 login(( 的 ftplib 文档
  2. 打开一个本地文件,用于写入要从FTP服务器检索的文件的内容。第一个参数是您要保存到的文件的文件名(它可以是任何内容,我决定使用与FTP服务器上的文件名相同的文件名(。第二个参数是您要打开文件的模式,它是一串标志:w = '写入模式',b = '二进制模式',因为我们要将文件检索为二进制并将其写入为二进制。
  3. 我建议您阅读 ftplib 文档以获取 retrbinary。起初这有点难以理解。第一个参数"RETR" + filename是发送到 FTP 服务器的命令,在本例中为RETR hello.txt。第二个参数f.write是您希望ftp.retrbinary函数在具有来自服务器的数据块时调用的回调函数。在其实现中,只要retrbinary有数据,它就会调用f.write(data)其中data是它拥有的最新数据块。要详细了解回调在 Python 中的工作原理,请参阅 Python 中的异步 API 简介

我希望这对你有用,我希望答案足够详细,让你了解它是如何工作的。如果它不起作用,请发布您收到的错误的堆栈跟踪输出。

这个问题有点过时了,但我自己没有找到任何最近的解决方案,所以我想我会提供我找到的解决方案。就我而言,办公室代理需要凭据,因此这些凭据包含在解决方案中。我假设您可以删除proxy_user并proxy_passwd如果您的代理不需要凭据。我在Python 3.6中得到的代码是:

from ftplib import FTP
ftp = FTP("officeproxy.com")
ftp.set_debuglevel(1)
ftp.login(user='ftp_user@ftp_host proxy_user', passwd='ftp_passwd', acct='proxy_passwd')
# Do whatever you need on the FTP server here
ftp.quit()

我希望这有所帮助。

最新更新