python使用代理进行邮件发送

2020年4月21日 评论 635 views 2877字阅读9分35秒

python使用代理进行邮件发送

前言

虽然说这里写的是SMTP发送邮件,但是核心代码是代理的使用

代理分为httphttpssocket4socket5这几种方式,这里主要是httpsocket5代理方式用python使用的体现

http代理

基于python2,但python3类似

import sys,os
import smtplib, httplib, socket

 class SMTP(smtplib.SMTP, httplib.HTTPConnection):
    def connect(self, host='localhost', port = 0, proxy=None):
        if proxy is None:
            return smtplib.SMTP.connect(self, host, port)
        else:
            if not port and (host.find(':') == host.rfind(':')):
                i = host.rfind(':')
                if i >= 0:
                    host, port = host[:i], host[i+1:]
                    try: port = int(port)
                    except ValueError:
                        raise socket.error, "nonnumeric port"
            if not port:
                port = self.default_port

            if self.debuglevel > 0:
            print >>sys.stderr, 'connect:', (host, port)

            proxy_host, proxy_port = proxy
            conn = httplib.HTTPConnection(proxy_host, proxy_port)
            conn.connect()
            conn.send("CONNECT %s:%d HTTP/1.0\r\n\r\n" % (host, port))
            response = conn.response_class(conn.sock, strict=conn.strict,
method=conn._method)
            (version, code, message) = response._read_status()
            if code != 200:
                conn.close()
                raise socket.error, "Proxy connection failed: %d %s" %
(code, message.strip())
            while True:
                line = response.fp.readline()
                if line == '\r\n':
                    break
            self.sock = conn.sock
            (code, msg) = self.getreply()
            if self.debuglevel > 0:
                print >>sys.stderr, "connect:", msg
            return (code, msg)

 if __name__ == '__main__':
    smtp = SMTP()
    smtp.debuglevel = 1
    smtp.connect('smtp.qq.com', 25, proxy=('127.0.0.1', 8123))
    smtp.login('1234...@qq.com', '12345678')
    smtp.close()

这种方式我当时是看某个地方的源码(具体哪个地方时间有点久远了忘记了),修改达到的,已经测试通过了

sockets5方式

python3会用到PySocks包,接下来就省略stmp了,只放代理链接的代码

from http.client import HTTPConnection
from urllib.parse import urlparse, urlencode

import socks

url = urlparse("http://final.destination.example.com:8888/")

conn = HTTPConnection('127.0.0.1', 9000) # use socks proxy address
conn.set_tunnel(url.netloc, url.port) # remote host and port that you actually want to talk to
conn.sock = socks.socksocket() # manually set socket
conn.sock.set_proxy(socks.PROXY_TYPE_SOCKS5,"127.0.0.1", 9000) # use socks proxy address
conn.sock.connect((url.netloc, url.port)) # remote host and port that you actually want to talk to

request_path ="%s?%s" % (url.path, url.query)
conn.request("POST", request_path, post_data)

这种方式来自 关于python:通过代理隧道httplib | 码农家园

sockets5带用户密码的方式

基于这种连接key:socks5://username:password@ip:port

# -*- coding:utf-8 -*-

# https://pypi.org/project/PySocks/
import urllib
import socks
import socket
from urllib import request
from urllib.error import URLError

username = "xxx"
password = "xxxx"
ip = "xxx.xxx.xxx.xxx"
port = 2349
# 在真实项目中建议加一下配置读取判断,是否要代理
# 下面两行代码建议包装后放到类中,用做成员变量构造返回
socks.set_default_proxy(socks.SOCKS5, ip, port, username=username, password=password)
socket.socket = socks.socksocket

url = 'http://httpbin.org/get'
try:
    req = urllib.request.Request(url=url, headers={
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'})
    response = urllib.request.urlopen(req)
    response = request.urlopen(url)
    print(response.read().decode('utf-8'))
except URLError as e:
    print(e)

测试成功

这种方式来自 python urllib socks5 auth username password 设置_Cocktail_py的博客-CSDN博客

最后

这篇文章,只记录了httpsockets5代理两种方式,另外两种没有记录,如果你有使用过,欢迎联系我,一起完善它

weinxin
公众号
在号内与我交流,回复【资源】获取技术大礼包
Python最后更新:2021-2-26
小熊