#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-прокси?