Как я могу получать электронные письма через POP или IMAP через прокси?

#python #imap

#python #прокси #imap #pop3

Вопрос:

Ни poplib, ни imaplib, похоже, не предлагают поддержку прокси, и я не смог найти много информации об этом, несмотря на мои попытки google-fu.

Я использую python для получения электронных писем с различных серверов с поддержкой imap / pop и должен иметь возможность делать это через прокси.

В идеале я хотел бы иметь возможность делать это напрямую на python, но использования оболочки (внешней программы / скрипта на основе OSX) для принудительного прохождения всего трафика через прокси может быть достаточно, если я не могу найти ничего лучшего.

Кто-нибудь может помочь мне? Я не могу себе представить, что я единственный, кому когда-либо приходилось получать электронные письма через прокси в python…

** РЕДАКТИРОВАТЬ заголовок, чтобы удалить HTTP, потому что я не должен печатать так быстро, когда я устал, извините за это, ребята **

Прокси, которые я планирую использовать, разрешают socks в дополнение к http.

Работа Pop или Imap через http не имела бы особого смысла (с сохранением состояния или без состояния), но я понимаю, что socks позволит мне делать то, что я хочу.

Пока единственным способом добиться того, чего я хочу, кажется, является грязный взлом imaplib … я бы предпочел избежать этого, если смогу.

Комментарии:

1. мне любопытно: как бы вы туннелировали imap через http-прокси даже без python?

2. Убрал Http из заголовка, моя ошибка, означала socks…

Ответ №1:

Вам не нужно грязно взламывать imaplib. Вы можете попробовать использовать пакет SocksiPy, который поддерживает socks4, socks5 и http-прокси (connect):

Что-то вроде этого, очевидно, вы хотели бы лучше обрабатывать параметры setproxy, используя дополнительные аргументы для пользовательского __init__ метода и т.д.

 from imaplib import IMAP4, IMAP4_SSL, IMAP4_PORT, IMAP4_SSL_PORT
from socks import sockssocket, PROXY_TYPE_SOCKS4, PROXY_TYPE_SOCKS5, PROXY_TYPE_HTTP

class SocksIMAP4(IMAP4):
    def open(self,host,port=IMAP4_PORT):
        self.host = host
        self.port = port
        self.sock = sockssocket()
        self.sock.setproxy(PROXY_TYPE_SOCKS5,'socks.example.com')
        self.sock.connect((host,port))
        self.file = self.sock.makefile('rb')
 

Вы могли бы сделать то же самое с IMAP4_SSL. Просто позаботьтесь о том, чтобы обернуть его в сокет ssl

 import ssl

class SocksIMAP4SSL(IMAP4_SSL):
    def open(self, host, port=IMAP4_SSL_PORT):
        self.host = host
        self.port = port
        #actual privoxy default setting, but as said, you may want to parameterize it
        self.sock = create_connection((host, port), PROXY_TYPE_HTTP, "127.0.0.1", 8118)
        self.sslobj = ssl.wrap_socket(self.sock, self.keyfile, self.certfile)
        self.file = self.sslobj.makefile('rb')
 

Комментарии:

1. Хорошая находка, это именно то, что я искал (не знал SocksiPy). Я попробую. Спасибо.

2. @rafael-t какой create_connection() метод в вашем коде? Где это реализовано?

3. @ВсеволодТимченко: эта конкретизированная реализация ssl была добавлена Рафаэлем Т., я не уверен create_connection , откуда он имеет в виду

4. @MattH да, я пытался обратиться к Рафаэлю, но движок SOF, очевидно, не поддерживает обращение к кому-то, кто внес изменения. Я полагаю, что это происходит из PySocks (строка 150). Этот метод должен быть socks.create_connection . Хотя спасибо за ответ. Есть также такая вещь, как self.sock закрытие после упаковки.

5. в socks нет sockssocket

Ответ №2:

Ответ на мой собственный вопрос… Есть быстрый и грязный способ заставить трафик из скрипта python проходить через прокси без проблем, используя Socksipy (спасибо, что указали мне этот путь)

 import socks
import socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4,proxy_ip,port,True)
socket.socket = socks.socksocket
 

Это переопределение глобального сокета, очевидно, немного жестоко, но работает как быстрое решение, пока я не найду время для правильного подкласса IMAP4 и IMAP4_SSL.

Комментарии:

1. у меня не сработало, я получил «IOError: [Ошибка сокета Errno] (‘время ожидания истекло’,)», есть какие-либо предложения?

Ответ №3:

Если я вас правильно понял, вы пытаетесь вставить квадратную привязку в круглое отверстие.

HTTP-прокси знает только, как «разговаривать» с HTTP, поэтому не может напрямую подключиться к POP или IMAP-серверу.

Если вы хотите это сделать, вам нужно где-нибудь внедрить свой собственный сервер для связи с почтовыми серверами. Он будет получать HTTP-запросы, а затем совершать соответствующие вызовы на почтовый сервер. Например.:

Насколько это было бы практично, я не знаю, поскольку вам пришлось бы преобразовать протокол с сохранением состояния в протокол без состояния.

Комментарии:

1. Вы на 100% правы, я забыл упомянуть о возможности socks. Я удалил HTTP из заголовка, извините за это, я устал; p

2. Метод «CONNECT» HTTP-прокси позволит вам запускать любой протокол tcp клиент-> сервер. ЕСЛИ HTTP-прокси позволяет это, большинство конфигураций по умолчанию ограничивают запросы «CONNECT» на порт 443.

3. Я понимаю, что вы имеете в виду, но как тогда thunderbird подключается через http-прокси?