简体   繁体   English

使用Python使用ftp设置代理

[英]Setting up proxy with ftp with Python

We are trying to develop a Python module that will hit an FTP server and download files to my local machine. 我们正在尝试开发一个Python模块,该模块将命中FTP服务器并将文件下载到我的本地计算机上。 When we try to run the FTP portion of the module it is timing out. 当我们尝试运行模块的FTP部分时,它正在超时。

We have a proxy server (let's call it "officeproxy.com:8080") to handle this and when using an FTP client like FileZilla or Windows Explorer to access FTP sites we are successful. 我们有一个代理服务器(简称为“ officeproxy.com:8080”)来处理此问题,并且在使用FileZilla或Windows资源管理器之类的FTP客户端访问FTP站点时,我们是成功的。

Let's call the ftp site "ftp.cal.com". 让我们将ftp站点称为“ ftp.cal.com”。 User name is "papa". 用户名是“ papa”。 Password is "tango123". 密码是“ tango123”。

So far we have: 到目前为止,我们有:

Proxy = officeproxy.com:8080

FTP = ftp.cal.com

User = papa

PW = tango123 

The above are not real entities so if you want to swap them out for real ones, be my guest. 以上不是真实实体,因此如果您想将它们换成真实实体,请成为我的客人。

I need a module to first load the proxy service then run the FTP portion. 我需要一个模块来首先加载代理服务,然后运行FTP部分。

I am running Python 2.7. 我正在运行Python 2.7。

I have searched around and have this code so far. 我到处搜索并获得了此代码。 The OP said it is just a short module to test connection to FTP and read one file. OP表示,这只是测试与FTP的连接并读取一个文件的简短模块。

(Note: I have intentionally put # in a lot of places to show when I don't know to fill in, or other reasons): (注意:我故意将#放在很多地方以显示我不知道填写的内容或其他原因):

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

Note, I found some similar questions on SO, but as the OP requested a detailed, beginner-level answer, I decided to post this. 注意,我在SO上发现了一些类似的 问题 ,但是当OP请求一个详细的,初学者级的答案时,我决定发布此问题。

To clarify, here is my understanding of what you want to accomplish: 为了澄清,这是我对要完成的工作的理解:

  • You have an FTP server behind a proxy. 您在代理后面有一个FTP服务器。
  • The FTP server requires user/password credentials, but the proxy itself does not. FTP服务器需要用户/密码凭据,但代理服务器本身不需要。

One option is to use the ftplib package. 一种选择是使用ftplib软件包。 One of the great advantages of a popular language such as Python is the wide selection of packages the that provide good implementations of specific functionality. 诸如Python之类的流行语言的最大优点之一是提供了特定功能的良好实现的广泛选择软件包。 In this case, an ftp client: 在这种情况下,一个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 

Here is what the code is doing: 这是代码的作用:

  1. Import the ftplib package. 导入ftplib软件包。
  2. Connect to the FTP server through the proxy. 通过代理连接到FTP服务器。 The way I have written it assume that the proxy is setup to forward the FTP protocol on the port specified (8080 in your example). 我编写它的方式假定已将代理设置为在指定的端口(本例中为8080)上转发FTP协议。 If this is not the case, this will not work. 如果不是这种情况,将无法使用。
  3. Enable debug logging. 启用调试日志记录。 From the ftplib documentation : ftplib文档中

FTP.set_debuglevel(level) : 0 , produces no debugging output... 1 produces a moderate amount of debugging output... 2 or higher produces the maximum amount of debugging output FTP.set_debuglevel(level)0 ,不产生调试输出... 1产生适中的调试输出... 2或更高版本产生最大的调试输出

  1. Login to the FTP server using user="papa", passwd="tango123". 使用user =“ papa”,passwd =“ tango123”登录到FTP服务器。 Again, this is from the ftplib documentation for login() 同样,这来自ftplib文档中的login()
  2. Open a local file for writing the contents of file you are about to retrieve from the FTP server. 打开一个本地文件,以写入要从FTP服务器检索的文件内容。 The first argument is the filename for the file you want to save to (it can be anything, I decided to use the same filename as the filename on the FTP server). 第一个参数是您要保存到的文件的文件名(可以是任何东西,我决定使用与FTP服务器上的文件名相同的文件名)。 The second argument is the mode you want to open the file as, which is a string of flags: w = 'write mode', b = 'binary mode', because we are going to retrieve the file as binary and write it as binary. 第二个参数是您要打开文件的模式 ,它是一串标志:w ='写入模式',b ='二进制模式',因为我们将以二进制形式检索文件并将其以二进制形式写入。
  3. I recommend you read the ftplib documentation for retrbinary . 我建议您阅读ftplib文档以获取retrbinary This is a bit tricky to understand at first. 首先,要理解这一点有些棘手。 The first argument, "RETR" + filename is the command to send to the FTP server, in this case RETR hello.txt . 第一个参数"RETR" + filename是发送到FTP服务器的命令,在本例中为RETR hello.txt The second argument, f.write is the callback function you want the ftp.retrbinary function to call whenever it has a block of data from the server. 第二个参数f.write是您希望ftp.retrbinary函数在ftp.retrbinary来自服务器的数据块时调用的回调函数。 In its implementation, whenever retrbinary has data, it will call f.write(data) where data is the latest block of data it has. 在其实现中,每当retrbinary有数据时,它将调用f.write(data) ,其中data是它拥有的最新数据块。 To understand more how callbacks work in Python, see Introduction to Asynchronous APIs in Python 要了解更多有关回调在Python中的工作方式的信息,请参见Python 中的异步API简介。

I hope this works for you, and I hope the answer is detailed enough that you understand how it works. 我希望这对您有用,并且希望答案足够详细,以使您了解它的工作原理。 If it does not work, please post the stack trace output for the error you get. 如果它不起作用,请发布堆栈跟踪输出以获取错误信息。

The question is a little bit out-dated, but I didn't find any recent solution myself so I figured I would provide the solution I found. 这个问题有点过时了,但是我本人没有找到任何最新的解决方案,因此我想我会提供找到的解决方案。 In my case the office proxy requires credentials so those are included in the solution. 就我而言,办公室代理需要凭据,因此这些凭据将包含在解决方案中。 I would presume that you can just remove the proxy_user and proxy_passwd if your proxy does not require credentials. 我想如果您的代理不需要凭据,就可以删除proxy_user和proxy_passwd。 The code I got working in Python 3.6 is: 我在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()

I hope this helps. 我希望这有帮助。

Adding this as it's one of the top results and struggled to find a solution. 将其添加为最重要的结果之一,并努力寻找解决方案。

If your proxy is a HTTP proxy and you need to authenticate it then this is how: 如果您的代理服务器是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
)

Otherwise for a FTP Proxy Martin's answer works. 否则,对于FTP代理,马丁的答案有效。 You can see the behaviour in FileZilla for FTP proxies too and that'll help to code for your requirements 您也可以在FileZilla中看到FTP代理的行为,这将有助于为您的要求编码

Hope this helps someone! 希望这对某人有帮助!

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

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