Python: how check emails with smtplib faster - python

I need to check a lot emails, thousands of emails.
I use smtplib to do it and I have some problem.
It's takes too much time (although I use multiprocessing and as usual 32 processes).
And sometimes I have an error to some email (timeout) or another error and I don't take any result for this.
But If I execute it again, I won't get an error, but can get errors for another email.
What I do wrong in my code and how can I improve that to have more accuracy and less errors.
def check_email(email, mxRecord):
time.sleep(2)
host = socket.gethostname()
try:
server = smtplib.SMTP()
server.set_debuglevel(0)
addressToVerify = email
server.connect(mxRecord)
server.helo(host)
server.mail('me#domain.com')
code, message = server.rcpt(str(addressToVerify))
server.quit()
if code == 250:
res_email = email
res = str(num) + ' ' + str(res_email)
print res
return res
else:
continue
except:
continue

you just loop throu all mail at the same time use threading...
def check_email(email, mxRecord):
time.sleep(2)
host = socket.gethostname()
for line, line 1 in itertools.izip(email, mxRecord)
try:
server = smtplib.SMTP()
server.set_debuglevel(0)
addressToVerify = email
server.connect(mxRecord)
server.helo(host)
server.mail('me#domain.com')
code, message = server.rcpt(str(addressToVerify))
server.quit()
if code == 250:
res_email = email
res = str(num) + ' ' + str(res_email)
print res
return res
else:
continue
except:
continue
m = threading.Thread(name='daemon', target=check_email(email,mxRecord))
m.setDaemon(True)
m.start()
sould look like this

Related

How can I make my current code send multiple emails using SMTP in Python

I am coding an assignment and got the code to successfully send an email to my email address. How can I correctly use a loop to ask the user if they want to send another email or quit. You can see how I attempted this but it doesn't seem to work. Additionally, How do I make it ask them to log into their outlook account and/or ask them the email address of the recipient?
Many thanks for taking time to read
This is the code:
from socket import *
import ssl
import base64
# Some global variables
SMTP_MAIL_SERVER = 'smtp-mail.outlook.com'
SMTP_TLS_PORT = 587
END_MESSAGE = '\r\n.\r\n'
client_socket = None
ssl_context = None
def send_line(line):
global client_socket
print('CLIENT: ' + line.strip())
client_socket.send(line.encode())
response = client_socket.recv(1024).decode()
return response
def get_code(response):
return int(response[:3])
def connect():
global client_socket
global ssl_context
print('CLIENT: Connecting to ' + SMTP_MAIL_SERVER)
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect((SMTP_MAIL_SERVER, SMTP_TLS_PORT))
response = client_socket.recv(1024).decode()
return response
def send_ehlo():
helo = 'ehlo smtp-mail.outlook.com\r\n'
return send_line(helo)
def send_helo():
helo = 'helo smtp-mail.outlook.com\r\n'
return send_line(helo)
def start_tls():
global client_socket
global ssl_context
response = send_line('STARTTLS \r\n')
ssl_context = ssl._create_stdlib_context()
client_socket = ssl_context.wrap_socket(client_socket, server_hostname=SMTP_MAIL_SERVER)
return response
def send_auth_request():
return send_line('auth login \r\n')
def send_username(username):
as_bytes = username.encode('ascii')
as_b64 = base64.b64encode(as_bytes)
as_utf8 = as_b64.decode('utf-8')
return send_line(as_utf8 + '\r\n')
def send_password(password):
as_bytes = password.encode('ascii')
as_b64 = base64.b64encode(as_bytes)
as_utf8 = as_b64.decode('utf-8')
return send_line(as_utf8 + '\r\n')
'''--------------------------------------------------------------------------------
TODO - Implement the functions below this point in order to send a test
email successfully using SMTP commands
--------------------------------------------------------------------------------'''
def send_mail_from(sender):
mail_from = 'MAIL FROM: <' + sender + '>\r\n'
return send_line(mail_from)
def send_rcpt_to(recipient):
rcpt_to = 'RCPT TO: <' + recipient + '>\r\n'
return send_line(rcpt_to)
def send_begin_data():
return send_line('DATA \r\n')
def send_message(subject, message):
subject_line = 'Subject: ' + subject + '\r\n'
body = '\nMessage:' + message + '\r\n'
return send_line(subject_line + body + END_MESSAGE)
def send_quit():
return send_line('QUIT \r\n')
'''--------------------------------------------------------------------------------
TODO - Implement the functions above this point in order to send a test
email successfully using SMTP commands
--------------------------------------------------------------------------------'''
send_email_question = 1
while send_email_question == 1:
def send_one_email():
# Open a TCP connection - the reply should start '220'
reply = connect()
print('SERVER: ' + reply)
# Send a EHLO command - the reply should be a list of supported
# 'enhanced' SMTP functions each starting '250'
reply = send_ehlo()
print('SERVER: ' + reply)
# Ask the server to switch to TLS - reply should start '220'
reply = start_tls()
print('SERVER: ' + reply)
# Send a HELO command encrypted - reply should start '220'
reply = send_helo()
print('SERVER: ' + reply)
# Send an AUTH LOGIN command
reply = send_auth_request()
print('SERVER: ' + reply)
# Send your (base64 encoded username) -
reply = send_username('#sending email username')
print('SERVER: ' + reply)
# Send your (base64 encoded username) -
reply = send_password('#sending email password')
print('SERVER: ' + reply)
# Send MAILFROM command - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply = send_mail_from('#sending email') #sending email
print('SERVER: ' + reply)
# Send RCPT TO command - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply=send_rcpt_to('#target email') #target email
print('SERVER: ' + reply)
# Send DATA command - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply = send_begin_data()
print('SERVER: ' + reply)
# Send the message (including subject) - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply = send_message(subject='Nothing much', message='Hello World')
print('SERVER: ' + reply)
# Quit the SMTP session - TODO - YOU IMPLEMENT THE FUNCTION BELOW
user_end_question = int(input("Please enter 1 if you would like to send another email 0 to end connection: "))
if user_end_question == 0:
reply = send_quit()
print('SERVER: ' + reply)
if __name__ == '__main__':
send_one_email()
When doing :
send_email_question = 1
while send_email_question == 1:
def send_one_email():
# ... [snip lots of send/reply]
user_end_question = int(input("Please enter 1 if you would like to send another email 0 to end connection: "))
if user_end_question == 0:
reply = send_quit()
print('SERVER: ' + reply)
if __name__ == '__main__':
send_one_email()
you are entering the loop, which creates a function (one def instruction). Then in the if __name__ you call one time the function which was created.
Instead, you should do :
def send_one_email():
# ... [snip lots of send/reply]
if __name__ == '__main__':
send_email_question = 1
while send_email_question == 1:
send_one_email()
user_end_question = int(input("Please enter 1 if you would like to send another email 0 to end connection: "))
if user_end_question == 0:
reply = send_quit()
print('SERVER: ' + reply)
which is creating the function (only once), then in a loop sending an email and asking whether to quit. This way, the send_one_email just sends one email, and do nothing else. And your "main" part decides how many times to call it.
99% of the time, you don't want to create functions (def) inside loops.

Having trouble with credentials (google smtp)

I'm a very new Python coder so please don't go too harsh on me, thanks.
I'm trying to make an emailer using smtplib and I'm having trouble with handing the users credentials to Google.
Full code:
mailcheck = input("This mailer is only for gmail, want to continue? (yes or no)")
# GMAIL SMTP INFORMATION
if mailcheck == "yes" or mailcheck == "Yes" or mailcheck == "y":
smtp_server = 'smtp.gmail.com'
port = 587
set_server = "gmail"
else:
print("Hey, sorry this program is only for Gmail")
#USER CREDENTIALS + RECEIVER
username = input("Google Email?")
password = input("Password?")
receiver = input("Who to send it to?")
subject = input("Subject of the email?")
econtents = input("What to put in the email?")
amount = input("Amount of emails to send?")
credentials = username + password
global d1
global d2
try:
server = smtplib.SMTP(smtp_server, port)
server.ehlo()
server.starttls()
server.login(username, password)
print("Sending" + amount, "to", receiver)
for i in range(1, int(amount) + 1):
message = "From" + credentials[0] + '\nSubject' + subject + '\n' + econtents
time.sleep(random.uniform(d1, d2))
server.sendmail(credentials[0], receiver, message)
print("\nEmail Sent!")
else:
print("Finished sending emails")
except smtplib.SMTPRecipientsRefused:
print("Recipient refused. Invalid email address?")
except smtplib.SMTPAuthenticationError:
print("Unable to authenticate with server. Ensure the details are correct.")
except smtplib.SMTPServerDisconnected:
print("Server disconnected for an unknown reason.")
except smtplib.SMTPConnectError:
print("Unable to connect to server.")
The error :
Unable to authenticate with server. Ensure the details are correct.
This means it went wrong with the login process. It should be going wrong somewhere in this part:
#USER CREDENTIALS + RECEIVER
username = input("Google Email?")
password = input("Password?")
receiver = input("Who to send it to?")
subject = input("Subject of the email?")
econtents = input("What to put in the email?")
amount = input("Amount of emails to send?")
credentials = username + password
global d1
global d2
try:
server = smtplib.SMTP(smtp_server, port)
server.ehlo()
server.starttls()
server.login(username, password)
print("Sending" + amount, "to", receiver)
for i in range(1, int(amount) + 1):
message = "From" + credentials[0] + '\nSubject' + subject + '\n' + econtents
time.sleep(random.uniform(d1, d2))
server.sendmail(credentials[0], receiver, message)
print("\nEmail Sent!")
I think it's because of the credentials = username + password which doesn't work, but I have no idea how I'd fix it.
If anyone knows what I'd have to change to fix this that'd be great!
Instead of adding those two strings, you're meaning to put them in an array. In Python, that's either
credentials = [username, password]
or
credentials = list(username, password)
But that doesn't seem to be your issue. Your issue is related to the login() function as you get the SMTPAuthenticationError exception. The smtplib documentation says that after running .starttls(), you should run .ehlo() again. Try to run that before logging in. Additionally, you could try to generate an SSL instance on port 465.
(Ctrl+F for .starttls())
https://docs.python.org/2/library/smtplib.html

Python: How is this error being generated and how can I fix it?

I'm working on a simple server based guessing game. Part of the client side of things is that there is an ssl secured admin client that can access the server to request information. I am currently trying to add the certificates and stuff to the requests however when running the (admittedly incomplete) file I get a 'ValueError: file descriptor cannot be a negative integer (-1)' at line 65 of the following code:
import select
import socket
import ssl
import random
def CreateGame():
number = random.randrange(1,21,1)
##print(number)
return number
def Greetings():
member.send("Greetings\r\n".encode())
def Far():
member.send("Far\r\n".encode())
def Close():
member.send("Close\r\n".encode())
def Correct():
member.send("Correct\r\n".encode())
def AdminGreetings():
member.send("Admin-Greetings\r\n".encode())
def Who():
responce = ""
for connection in clientList:
if connection != member:
responce += str(clientList[connection])
member.send((str(responce)).encode())
member.close()
reader_list.remove(member)
del clientList[member]
def GameLogic(mNumber):
if("Guess: " + str(mNumber) + "\r\n" == guess):
Correct()
elif(("Guess: " + str(mNumber-3) + "\r\n" == guess) or
("Guess: " + str(mNumber-2) + "\r\n" == guess) or
("Guess: " + str(mNumber-1) + "\r\n" == guess) or
("Guess: " + str(mNumber+1) + "\r\n" == guess) or
("Guess: " + str(mNumber+2) + "\r\n" == guess) or
("Guess: " + str(mNumber+3) + "\r\n" == guess) ):
Close()
else:
Far()
#client socket
s1 = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s1.bind(('',4000))
s1.listen(5)
#admin socket
s2 = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s2.bind(('',4001))
s2.listen(5)
reader_list = [s1,s2]
clientList = {}
mNumber = CreateGame()
while True:
(read,write,error) = select.select(reader_list,[],[])
for member in read:
if member == s1:
(read,write) = s1.accept()
reader_list.append(read)
elif member == s2:
(read,write) = s2.accept()
reader_list.append(read)
sslSocket = ssl.wrap_socket(member,
keyfile="5cc515_server.key",
certfile="5cc515_server.crt",
server_side = True,
cert_reqs = ssl.CERT_REQUIRED,
ca_certs="5cc515_root_ca.crt")
else:
try:
message = member.recv(4092).decode()
sockAddr = member.getsockname()
if(message == "Hello\r\n"):
addr = str(sockAddr[0]) + " " + str(sockAddr[1]) + "\r\n"
clientList[member] = addr
if (sockAddr[1] == 4001):#is using port 4000
try:
ssl_s = ssl.wrap_socket(member,
keyfile="5cc515_server.key",
certfile="5cc515_server.crt",
server_side = True,
cert_reqs = ssl.CERT_REQUIRED,
ca_certs="5cc515_root_ca.crt")
##handshake stuff
AdminGreetings()
except:
break
else:
Greetings()
elif(message == "Who\r\n"):
##handshake stuff
Who()
else:
##print("try and assign guess")
guess = message
##print("game logic")
GameLogic(mNumber)
except:
print("recv failed")
member.close()
reader_list.remove(member)
del clientList[member]
break
I understand that without the crt and key this cant really be debugged, but since nothing is making changes to the reader_list[] i dont see why it goes from 2 to -ve...
anyway here is the other part (the admin client)
import socket
import select
import ssl
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
handshake = False
# send Hello
try:
while handshake == False:
print("create ssl socket")
sslSocket = ssl.wrap_socket(s,
keyfile="100297626.key",
certfile="100297626.crt",
server_side = False,
ca_certs="5cc515_root_ca.crt")
print("connect")
sslSocket.connect(("127.0.0.1", 4001))
print("send hello")
sslSocket.write("Hello\r\n".encode())
print("rec hello")
sslSocket.recv(80).decode()
sslSocket.send("Who\r\n".encode())
print(sslSocket.recv(4092).decode())
except:
print("Server Unavailable")
s.close()
Thanks in advance!
As line 65 is:
(read,write,error) = select.select(reader_list,[],[])
One must infer that the error comes from passing a socket with a fd of -1 to select.select in its read_list. Please run your code again but include the check that:
assert all(s.fileno() != -1 for s in reader_list)

Gmail not accepting logins in email program

This program works quite well except for when dealing with logging in with Gmail. I wasn't quite sure if this was a problem with Gmail specifically, or a problem with my program. Comcast, AOL, and Yahoo! work fine.
import socket
import smtplib
email_provider = raw_input('Gmail, AOL, Yahoo! or Comcast? ').title()
email_user = raw_input('Type in your full email username. ')
email_pwd = raw_input('Type in your email password. ')
if email_provider == 'Gmail' or 'Google':
smtpserver = smtplib.SMTP("smtp.gmail.com",587)
if email_provider == 'Aol' or 'AOL':
smtpserver = smtplib.SMTP("smtp.aol.com",587)
if email_provider == 'Yahoo' or 'Yahoo!':
smtpserver = smtplib.SMTP("smtp.mail.yahoo.com",587)
if email_provider == 'Comcast' or 'Xfinity':
smtpserver = smtplib.SMTP("smtp.comcast.net",587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo
smtpserver.login(email_user, email_pwd)
sendto = raw_input('Email address to send message to: ')
to = sendto
CC = sendto
subj = raw_input('Subject: ')
header = 'To: ' + to + '\n' + 'From: ' + email_user + '\n' + 'Subject:' + subj +'\n'
print '\nMessage Details:'
print (header)
assignment=raw_input('Enter your message: ')
msg = header + assignment + '\n'
smtpserver.sendmail(email_user, to, msg)
print ('Your message has been sent!')
smtpserver.close()
This is a problem:
if email_provider == 'Gmail' or 'Google':
Python works on truthy values. Anything that isn't False, None, 0 or an empty collection/mapping will be True.
From what it looks like, the execution chain will fall all the way through until it sets your SMTP connection credentials to Comcast's server.
So, effectively, your first statement is saying this:
if email_provider == 'Gmail' or True
You would want to change it to this:
if email_provider in ('Gmail', 'Google')
Then, realistically, those could be rewritten as elif - only one of those statements are going to be true at any given time.

Python smtplib sometimes fails sending

I wrote a simple "POP3S to Secure SMTP over TLS" MRA script in Python (see below).
It works fine, but sometimes it returns "Connection unexpectedly closed" while trying to send via SMTP. Running the script again will deliver that message successfully.
Please give me some suggestions why it would fail to deliver a message sometimes but at the next run it delivers exactly this message successfully!?
#! /usr/bin/env python
import poplib
import email
def forward_pop3_smtp( smtp_credentials, pop3_credentials, forward_address):
pop3_server = pop3_credentials[0]
pop3_port = pop3_credentials[1]
pop3_user = pop3_credentials[2]
pop3_password = pop3_credentials[3]
message_recipient = forward_address
server = poplib.POP3_SSL( pop3_server, pop3_port)
server.user( pop3_user)
server.pass_( pop3_password)
for messages_iterator in range( len( server.list()[1])):
message_list = server.retr( messages_iterator + 1)[1]
message_string = ''
for message_line in message_list:
message_string += message_line + '\n'
message_message = email.message_from_string( message_string)
message_message_as_string = message_message.as_string()
message_sender = message_message[ 'From']
print( 'message_sender = ' + message_sender)
smtp_return = send_smtp( smtp_credentials, message_sender, message_recipient, message_message_as_string)
print( 'smtp_return = ' + str(smtp_return))
if smtp_return == 0:
print( 'Deleting message ' + message_message[ 'Subject'] + ':\n')
return_delete = server.dele( messages_iterator + 1)
print( 'return_delete = \n' + str(return_delete))
print( '\n')
server.quit()
def send_smtp( smtp_credentials, message_sender, message_recipient, message_message_as_string):
smtp_server = smtp_credentials[0]
smtp_port = smtp_credentials[1]
smtp_user = smtp_credentials[2]
smtp_password = smtp_credentials[3]
import smtplib
exception = 0
try:
server = smtplib.SMTP( smtp_server)
server.starttls()
server.login( smtp_user, smtp_password)
smtp_sendmail_return = server.sendmail( message_sender, message_recipient, message_message_as_string)
server.quit()
except Exception, e:
exception = 'SMTP Exception:\n' + str( e) + '\n' + str( smtp_sendmail_return)
return exception
if __name__ == '__main_':
print( 'This module needs to be imported!\n')
quit()
Use Port 587 for TLS. I don't see the script use smtp_port
Use like,
server = smtplib.SMTP( smtp_server, int(smtp_port)
For Secure SMTP (SMTP + SSL), use smtplib.SMTP_SSL

Categories