Come inviare una posta a centinaia di migliaia di destinatari in Python velocemente che ciascuno dei destinatari è mostrato come ricevitore nell'intestazione della posta? [Chiuso

StackOverflow https://stackoverflow.com/questions/8381210

Domanda

Sto cercando soluzioni per inviare un numero enorme di posta (centinaia di migliaia) a Python. Ho un elenco di destinatari (in un file) e voglio inviare una posta a tutti. Voglio che ciascuno dei destinatari sia stato mostrato come ricevitore nell'intestazione della posta, non BCC o CC. Bene, le mie soluzioni: inviare una posta separata a ciascuno di essi non una posta a tutti gli elenchi. Ho fatto alcune opere di seguito: (ho usato Smtplib, filo):

class SendMail(threading.Thread):
  def __init__(self, from, to, subject, message):
     self.from = from
     self.to = to
     self.subject = subject
     self.message = message 
  def run(self):
    try:
                msg = MIMEMultipart('alternative')
                msg['Subject'] = self.subject
                msg['From'] = self.from
                msg['To'] = self.to
                msg.attach(MIMEText(self.message , 'html'))
                server = smtplib.SMTP()              
                server.connect('xxxxx', 25)
                server.login('cxxxxx', 'yyyyyy')                
                server.sendmail(self.from, self.to, msg.as_string())
    except:
          pass

def sendmail():
   f = open('recipients','w')
   from = "me@mail.test"
   subject = "hello"
   message = "Hello Hello"
   for line in f.readlines():
      t = SendMail(from, line, subject, message)
      t.run()
   f.close()

Funziona ma molto lento (circa 6 mail/secondo). Quindi per favore aiutami a renderlo più veloce. Oppure mi suggeriscono un'altra soluzioni per fare questo lavoro. Grazie mille!

È stato utile?

Soluzione

Il più veloce sarebbe installare un agente di trasferimento di posta come Postfix sulla tua macchina e consegna tutte le tue e -mail per la consegna utilizzando il /usr/sbin/sendmail interfaccia postale. La maggior parte dei server di posta ragionevole possono accettare migliaia di messaggi di posta per la consegna al secondo e possono eseguire alcuni pipelining SMTP per inviare un messaggio a più destinatari su un dominio target in un'unica connessione, riducendo drasticamente le spese generali del traffico e migliorando il rendimento del messaggio. (Ciò non influenzerebbe il modo in cui i tuoi utenti vedono le tue e -mail.)

La maggior parte dei server di posta può anche gestire temporaneamente i server straordinariamente bene, il che è estremamente importante poiché molti siti usano Greylisting per combattere lo spam.

Se, tuttavia, vuoi davvero contattare un server SMTP tramite una connessione di rete nel tuo Python, sarebbe un'ottima idea usare un pool di fili di inviare thread che elimineranno gli indirizzi da una coda, crea e invieranno l'e -mail, quindi torneranno alla coda per un altro indirizzo al servizio. Il tuo codice attuale crea e distrugge un nuovo thread per ogni singola consegna di posta. I thread impiegano del tempo per creare e dedicare del tempo a distruggere, e tutto ciò che sovraccarico è il tempo che avrebbe potuto essere speso al servizio della posta.

Inoltre, il pool di thread limiterebbe il numero totale di connessioni attive. Non ha senso creare 1000 connessioni separate ma simultanee a un singolo server di posta. Il strette di mano a tre vie Ciò impostato ogni sessione prendi tre volte la latenza sul server per stabilire la sessione TCP prima di poter inviare qualsiasi traffico SMTP. Quindi crea dieci thread con dieci connessioni e riutilizzare tali connessioni per l'invio di e -mail. (Anche dieci sono probabilmente eccessivi per questo - due o tre probabilmente funzionerebbero meglio. Diamine, uno Il thread potrebbe essere il migliore di tutto, anche se quella connessione scende (limiti di posta per connessione?) Avresti un periodo di invio niente sopra il filo fino a quando tale connessione non viene ristabilita.)

Quello che hai creato ora è molto simile al Problema di mandria che vaga - Inizi centinaia o migliaia di thread ma potresti non avere una memoria sufficiente per tenerli tutti in RAM contemporaneamente. Potresti aver introdotto abbastanza scambio per ridurre drasticamente le prestazioni del sistema di invio, in cui un singolo thread di esecuzione potrebbe adattarsi interamente in memoria ed eseguire senza stallo per lo scambio.

Altri suggerimenti

La mia raccomandazione (e di gran lunga la più semplice) è di scaricare questo lavoro su una terza parte e chiamare le loro biblioteche all'interno del tuo codice.

Mailchimp sembra essere abbastanza popolare (ecco il loro API). Offrono anche un generoso piano gratuito.

Socketlabs è un'altra opzione (ecco il loro API). Google dovrebbe fornirti tonnellate di altri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top