I am using pd.to_html for sending my pandas dataframe over email, the emails are opening fine in Gmail browser with all the tables in the email body. But they are not opening in Outlook all the tables are going as an HTML attachment in outlook.
Using the following code for converting my dataframe to HTML.
df_1 = df_1.to_html(index=False,header= True,border=4,justify = 'left',col_space =9)
from IPython.core.display import display, HTML
display(HTML(df_1))
This is how I am sending the Email:-
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
email_user = 'xyz#x.com'
email_password = '*********'
email_send = 'xyz#x.com'
subject = 'ABCDEF'
msg = MIMEMultipart()
msg['From'] = email_user
msg['To'] = email_send
msg['Subject'] = subject
body_1 = """ Hey All,
Please find the data:
"""
msg.attach(MIMEText(body_1,'plain'))
msg.attach(MIMEText(df_1,'html'))
text = msg.as_string()
server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()
server.login(email_user,email_password)
server.sendmail(email_user,email_send.split(','),text)
server.quit()
There are no error's email is opening in Gmail properly. But in outlook tables are coming as an attachment.
You can make a single attachment as html.That worked for me.
df_1 = df_1.to_html(index=False,header= True,border=4,justify = 'left',col_space =9)
mailBody= """<p> Hi All, <br><br>
Please find the data: </p> <br><br>
""" + df_1 + """<br> Thanks. """
msg.attach(MIMEText(mailBody,'html'))
Related
So I'm trying to send an e-mail from Excel with Python. Right now I just have all the e-mails set up in column A1 separated by semicolons. If I put the e-mails into Python directly, they send out but when I use the Python call-out, it freaks out giving me this error. How exactly can I make this work?
import smtplib
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import pandas
from datetime import datetime
server = smtplib.SMTP('relay.xxx.com')
email_df = pandas.read_excel(f"E-mails.xlsx", sheet_name="Emails", nrows=1, usecols = "A")
sender = 'email#email.com'
receivers = 'Email'
receivers = list(email_df)
print(receivers)
msg = MIMEMultipart('related')
msg['Subject'] = 'Test mail'
msg['From'] = sender
with smtplib.SMTP('relay.xxx.com') as server:
msg['To'] = receivers
server.sendmail(sender, receivers, bytes(msg.as_string()))
print(f"Successfully sent email to: {receivers}")
I don't want multiple e-mails to be sent out. I want 1 single e-mail with a bunch of e-mails in the address box.
Alternatively, if there's a way can read it by column, (addr1 in a1, addr in a2) that'd also be better.
Appreciate it.
If you can get your email addresses (from your df) into a list in the desired format, e.g.:
print(receivers)
['email1#email1.com', 'email2#email2.com', 'email3#email3.com']
then you can add this after its assignment to turn it into a string for send_mail (as it requires a string instead of a list):
receivers = ", ".join(receivers)
You mention that it would be ideal if you had an email address per row under column A in your spreadsheet. So if you can get your Excel spreadsheet into this format (with a column heading of "Email") then you can do this to get the aforementioned list:
email_df = pandas.read_excel(f"E-mails.xlsx", sheet_name="Emails", usecols = "A")
receivers = email_df['Email'].tolist()
So, for completeness (with Excel spreadsheet in its new format of one email address per row under column A), your code would change to:
import smtplib
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import pandas
from datetime import datetime
server = smtplib.SMTP('relay.xxx.com')
email_df = pandas.read_excel(f"E-mails.xlsx", sheet_name="Emails")
receivers = email_df['Email'].tolist()
print(receivers) # Check list is one valid email address per element
receivers = ", ".join(receivers)
sender = 'email#email.com'
msg = MIMEMultipart('related')
msg['Subject'] = 'Test mail'
msg['From'] = sender
with smtplib.SMTP('relay.xxx.com') as server:
msg['To'] = receivers
server.sendmail(sender, receivers, bytes(msg.as_string(), encoding='utf-8'))
print(f"Successfully sent email to: {receivers}")
If you build a message, you'd better use the send_message interface. And I would suggest to use the newer EmailMessage interface which is cleaner and simpler that the older MimeMultipart one:
import smtplib
from email.message import EmailMessage
...
msg = EmailMessage()
msg['Subject'] = 'Test mail'
msg['From'] = sender
msg.set_payload('Message text.\nLine 2...')
# or eventually add parts with msg.add_related(...), msg.add_alternative(..)
# or msg.add_attachment(...)
with smtplib.SMTP('relay.xxx.com') as server:
msg['To'] = receivers
server.send_messages(msg)
print(f"Successfully sent email to: {receivers}")
I am learning how to use Python for automating emails, and am facing issues in creating a "clean" email.
Problem: I have a Google doc which has a certain text, followed by an image, followed by some text. I wish to use this as the content of an email, which I wish to send using Python
Approach: Based on what I read on SO and blogs, I used MIMEMultipart and broke my original doc into 3 parts: text, image, text and I downloaded the html versions for both the text files. Thereafter, I used the following code:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from string import Template
me = "myemail#gmail.com"
you = "youremail#gmail.com"
msg = MIMEMultipart()
msg['From'] = me
msg['To'] = you
msg['Subject'] = 'This is a test'
html1 = open('test_doc_part1.html')
part1 = MIMEText(html1.read(), 'html')
msg.attach(part1)
html1.close()
image_text = MIMEText('<img src="cid:image1">', 'html')
msg.attach(image_text)
fp = open('test_image.jpg', 'rb')
image = MIMEImage(fp.read())
fp.close()
image.add_header('Content-ID', '<image1>') # Define the image's ID as referenced in the HTML body above
msg.attach(image)
html2 = open('test_doc_part2.html')
part2 = MIMEText(html2.read(), 'html')
msg.attach(part2)
html2.close()
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(me, "password")
text = msg.as_string()
# Do text substitutions here
server.sendmail(from_addr= me, to_addrs= you, msg=text)
server.quit()
Issue: Depending on the text sources, the text of my email is either hidden under the image, or all/some of it is underlined/garbled. I'm using gmail and viewing this email in Google Chrome. The original content of the received email can be viewed here. Can someone point out where I'm incorrect?
I have a HTML file which is essentially a table. However some of the cells in the table are highlighted and when I convert my HTML file to text as specified in other stackoverflow answers, the coloring of the cells and other CSS specifications disappear in the mail.
Code :
import smtplib
import csv
from tabulate import tabulate
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
text = open("final.html", 'r').read()
message = MIMEMultipart(
"alternative", None, [MIMEText(text), MIMEText(text,'html')])
server = smtplib.SMTP('smtp.gmail.com', 25)
server.connect("smtp.gmail.com",25)
server.ehlo()
server.starttls()
server.ehlo()
server.login('mail', "password")
server.sendmail('from_mail', 'to_mail', message.as_string())
server.quit()
Finally, the message is converted to string as in message.as_string(). I guess when the message is converted to a string, the CSS formatting options are taken away.
HTML input file :
final.html file
Current output in mail:
Any help would be appreciated. Thanks a lot !
Firstly, most email clients don't support External CSS within the mail. This can be converted to Inline CSS with premailer.
import smtplib
import ssl
import premailer
from email.message import EmailMessage
SERVER_ADDRESS = "smtp.gmail.com"
SERVER_PORT = 587
EMAIL_ADDRESS = 'your email'
EMAIL_PASSWORD = 'your email password'
RECIPIENT_EMAIL = 'recipient's mail'
text = open("final.html", 'r').read()
text = premailer.transform(text)
msg = EmailMessage()
msg['Subject'] = "the subject"
msg['From'] = EMAIL_ADDRESS
msg['To'] = RECIPIENT_EMAIL
msg.set_content('content')
msg.add_alternative(text, subtype='html')
# Create a SSLContext object with default settings.
context = ssl.create_default_context()
with smtplib.SMTP(SERVER_ADDRESS, SERVER_PORT) as smtp:
smtp.ehlo()
smtp.starttls(context=context)
smtp.ehlo()
smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
smtp.send_message(msg)
This github repo was helpful.
I am trying to send emails from the Cpanel email but everything I try I face the same error
[Errno 11001] getaddrinfo failed
this is my code, I tried it with Google domain and it works fine but the Cpanel is not working ? is there a way around it to use python for sending emails ?
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from email.mime.image import MIMEImage
email_user = 'something#Mydomain.com'
email_password = 'password'
email_send = "someemail#gmail.com"
subject = "Testing 2"
msg = MIMEMultipart()
msg['From'] = email_user
msg['To'] = email_send
msg['Subject'] = subject
h = str("Holder")
c = str("course")
t = str("trainer")
html = """\
<html>
<head></head>
<body>
<p >Hello {h} This {t} we need your conf. on {c} </p>
</body>
</html>
""".format(h=h , c=c , t=t)
msg.attach(MIMEText(html,'html'))
server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()
server.login(email_user,email_password)
server.sendmail(email_user,email_send,msg.as_string())
server.quit()
So what do you think?
yes you have to change server = smtplib.SMTP('yourDomain.com',25)
In addition to this thread send outlook mail via win32com, i'd like to know if there is a possibility to use mail.From alike method. When you create an email, you can choose from what email you'd like to send it.
And for the future, where could i get this information from? I mean do those commands work with COM object of outlook application?
Here's a code which I have been using for long time and hopefully will work for you as well,
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
def sendMail(to, subject, text):
assert type(to)==list
fro = "abc#xyz.com" # use your from email here
msg = MIMEMultipart()
msg['From'] = fro
msg['To'] = COMMASPACE.join(to)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg.attach(MIMEText(html, 'html'))
smtp = smtplib.SMTP('mailhost.abcd.co.in') #use your mailhost here, it's dummy.
smtp.sendmail("", to, msg.as_string() )
smtp.close()
TOADDR = ['abc#xyz.com'] # list of emails address to be sent to
html = """\
<html>
<head></head>
<body>
<p>Hi!<br>
How are you?<br>
Here is the link you wanted.
</p>
</body>
</html>
"""
sendMail( TOADDR, "hello",html)