Python smtplib代理支持

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服务器。成功登录后,我会发送电子邮件。它的工作原理很好,但当我看电子邮件标题时,我可以看到我的主机名。我想通过一个代理来代替它


非常感谢您的帮助。

我昨天遇到了类似的问题,这是我为解决此问题而编写的代码。它无形中允许您通过代理使用所有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()