Python smtplib代理支持
我想通过代理发送电子邮件 我目前的执行情况如下: 我通过身份验证连接到smtp服务器。成功登录后,我会发送电子邮件。它的工作原理很好,但当我看电子邮件标题时,我可以看到我的主机名。我想通过一个代理来代替它Python smtplib代理支持,python,proxy,smtp,smtplib,Python,Proxy,Smtp,Smtplib,我想通过代理发送电子邮件 我目前的执行情况如下: 我通过身份验证连接到smtp服务器。成功登录后,我会发送电子邮件。它的工作原理很好,但当我看电子邮件标题时,我可以看到我的主机名。我想通过一个代理来代替它 非常感谢您的帮助。我昨天遇到了类似的问题,这是我为解决此问题而编写的代码。它无形中允许您通过代理使用所有smtp方法 #!/usr/bin/env python # -*- coding: utf-8 -*- # # smtprox.py # Shouts to sui
非常感谢您的帮助。我昨天遇到了类似的问题,这是我为解决此问题而编写的代码。它无形中允许您通过代理使用所有smtp方法
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# smtprox.py
# Shouts to suidrewt
#
# ############################################# #
# This module allows Proxy support in MailFux. #
# Shouts to Betrayed for telling me about #
# http CONNECT #
# ############################################# #
import smtplib
import socket
def recvline(sock):
stop = 0
line = ''
while True:
i = sock.recv(1)
if i == '\n': stop = 1
line += i
if stop == 1:
break
return line
class ProxSMTP( smtplib.SMTP ):
def __init__(self, host='', port=0, p_address='',p_port=0, local_hostname=None,
timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
"""Initialize a new instance.
If specified, `host' is the name of the remote host to which to
connect. If specified, `port' specifies the port to which to connect.
By default, smtplib.SMTP_PORT is used. An SMTPConnectError is raised
if the specified `host' doesn't respond correctly. If specified,
`local_hostname` is used as the FQDN of the local host. By default,
the local hostname is found using socket.getfqdn().
"""
self.p_address = p_address
self.p_port = p_port
self.timeout = timeout
self.esmtp_features = {}
self.default_port = smtplib.SMTP_PORT
if host:
(code, msg) = self.connect(host, port)
if code != 220:
raise SMTPConnectError(code, msg)
if local_hostname is not None:
self.local_hostname = local_hostname
else:
# RFC 2821 says we should use the fqdn in the EHLO/HELO verb, and
# if that can't be calculated, that we should use a domain literal
# instead (essentially an encoded IP address like [A.B.C.D]).
fqdn = socket.getfqdn()
if '.' in fqdn:
self.local_hostname = fqdn
else:
# We can't find an fqdn hostname, so use a domain literal
addr = '127.0.0.1'
try:
addr = socket.gethostbyname(socket.gethostname())
except socket.gaierror:
pass
self.local_hostname = '[%s]' % addr
smtplib.SMTP.__init__(self)
def _get_socket(self, port, host, timeout):
# This makes it simpler for SMTP_SSL to use the SMTP connect code
# and just alter the socket connection bit.
if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
new_socket = socket.create_connection((self.p_address,self.p_port), timeout)
new_socket.sendall("CONNECT {0}:{1} HTTP/1.1\r\n\r\n".format(port,host))
for x in xrange(2): recvline(new_socket)
return new_socket
使用:
smtplib
模块不包括通过HTTP代理连接到SMTP服务器的功能。这个方法对我不起作用,显然是因为我的HTTP代理只接收编码的消息。我基于ryos的代码编写了以下自定义类,它运行良好。(但是,您的里程数可能会有所不同。)
要连接到SMTP服务器,只需使用类proxymtp
而不是smtplib.SMTP
proxy_host = YOUR_PROXY_HOST
proxy_port = YOUR_PROXY_PORT
# Both port 25 and 587 work for SMTP
conn = ProxySMTP(host='smtp.gmail.com', port=587,
p_address=proxy_host, p_port=proxy_port)
conn.ehlo()
conn.starttls()
conn.ehlo()
r, d = conn.login(YOUR_EMAIL_ADDRESS, YOUR_PASSWORD)
print('Login reply: %s' % r)
sender = 'from@fromdomain.com'
receivers = ['to@todomain.com']
message = """From: From Person <from@fromdomain.com>
To: To Person <to@todomain.com>
Subject: SMTP e-mail test
This is a test e-mail message.
"""
print('Send email.')
conn.sendmail(sender, receivers, message)
print('Success.')
conn.close()
proxy\u host=您的\u proxy\u主机
proxy\u port=您的\u proxy\u port
#端口25和587都适用于SMTP
conn=proxystp(host='smtp.gmail.com',port=587,
p_地址=代理_主机,p_端口=代理_端口)
康涅狄格州埃洛
康涅狄格州斯塔特尔斯
康涅狄格州埃洛
r、 d=conn.login(您的电子邮件地址、密码)
打印('登录回复:%s'%r]
发送者from@fromdomain.com'
接收者=['to@todomain.com']
message=“”发件人:发件人
致:致人
主题:SMTP电子邮件测试
这是一封测试电子邮件。
"""
打印('发送电子邮件')
conn.sendmail(发件人、收件人、邮件)
打印('成功')
康涅狄格州关闭
这个代码是我挣来的。
1.文件名不能是email.py重命名文件名,例如emailSend.py
2.允许谷歌从不可靠的来源发送消息是必要的。似乎没有发送电子邮件,它只是坐在那里等待。还尝试了几个不同的代理。正如@Sinista所说,您的代码不起作用,而只是挂在那里。我已经冒昧地修好了,所以现在它对我来说很好用。官方版本不适用于此。改用。同样的,只是一个更新:SocksPy有点过时,请改用
pip安装pysocks
还请注意,尝试通过HTTP代理使用SMTP通常是不可能的,必须获得SOCKS代理。我个人使用Tor,你可以阅读如何设置Tor代理。PySocks有一个非常有用的函数,名为create_connection
,它使修补smtplib与代理一起工作变得非常容易。只需查看\u get_socket
in。因为我遇到了它,在这里没有看到它:socks.warpmodule(smtplib)
的副作用是其他库也被修补(例如请求
)。更好的方法是不使用monkeypatching,就像@mkerrig所说的,查看SMTP。获取\u socket
并使用socks。创建\u连接
。错误是什么?代码引发IOError,接收行:HTTP/1.1 412前置条件失败,接收行:缓存控制:无缓存,IOError:[Errno-1]ma:无缓存您的代码不工作。给出错误-AttributeError:ProxyStp实例没有属性“local_hostname”Get卡在连接到代理上。发送连接。接收线路。
:(有没有办法解决这个问题?
import smtplib
import socket
def recvline(sock):
"""Receives a line."""
stop = 0
line = ''
while True:
i = sock.recv(1)
if i.decode('UTF-8') == '\n': stop = 1
line += i.decode('UTF-8')
if stop == 1:
print('Stop reached.')
break
print('Received line: %s' % line)
return line
class ProxySMTP(smtplib.SMTP):
"""Connects to a SMTP server through a HTTP proxy."""
def __init__(self, host='', port=0, p_address='',p_port=0, local_hostname=None,
timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
"""Initialize a new instance.
If specified, `host' is the name of the remote host to which to
connect. If specified, `port' specifies the port to which to connect.
By default, smtplib.SMTP_PORT is used. An SMTPConnectError is raised
if the specified `host' doesn't respond correctly. If specified,
`local_hostname` is used as the FQDN of the local host. By default,
the local hostname is found using socket.getfqdn().
"""
self.p_address = p_address
self.p_port = p_port
self.timeout = timeout
self.esmtp_features = {}
self.default_port = smtplib.SMTP_PORT
if host:
(code, msg) = self.connect(host, port)
if code != 220:
raise IOError(code, msg)
if local_hostname is not None:
self.local_hostname = local_hostname
else:
# RFC 2821 says we should use the fqdn in the EHLO/HELO verb, and
# if that can't be calculated, that we should use a domain literal
# instead (essentially an encoded IP address like [A.B.C.D]).
fqdn = socket.getfqdn()
if '.' in fqdn:
self.local_hostname = fqdn
else:
# We can't find an fqdn hostname, so use a domain literal
addr = '127.0.0.1'
try:
addr = socket.gethostbyname(socket.gethostname())
except socket.gaierror:
pass
self.local_hostname = '[%s]' % addr
smtplib.SMTP.__init__(self)
def _get_socket(self, port, host, timeout):
# This makes it simpler for SMTP to use the SMTP connect code
# and just alter the socket connection bit.
print('Will connect to:', (host, port))
print('Connect to proxy.')
new_socket = socket.create_connection((self.p_address,self.p_port), timeout)
s = "CONNECT %s:%s HTTP/1.1\r\n\r\n" % (port,host)
s = s.encode('UTF-8')
new_socket.sendall(s)
print('Sent CONNECT. Receiving lines.')
for x in range(2): recvline(new_socket)
print('Connected.')
return new_socket
proxy_host = YOUR_PROXY_HOST
proxy_port = YOUR_PROXY_PORT
# Both port 25 and 587 work for SMTP
conn = ProxySMTP(host='smtp.gmail.com', port=587,
p_address=proxy_host, p_port=proxy_port)
conn.ehlo()
conn.starttls()
conn.ehlo()
r, d = conn.login(YOUR_EMAIL_ADDRESS, YOUR_PASSWORD)
print('Login reply: %s' % r)
sender = 'from@fromdomain.com'
receivers = ['to@todomain.com']
message = """From: From Person <from@fromdomain.com>
To: To Person <to@todomain.com>
Subject: SMTP e-mail test
This is a test e-mail message.
"""
print('Send email.')
conn.sendmail(sender, receivers, message)
print('Success.')
conn.close()