简体   繁体   中英

Iterate through data frame rows to send email

I have a data frame that looks like this:

|num|data |     email       |
|-- | --- | --------------- |
|1  | x   |user1@example.com|
|2  | y   |user1@example.com|
|3  | z   |user2@example.com|

I need to send the 'num', 'data', fields to the email in the 'email' column.

So for this dataframe, rows 1 and 2 would be sent to user1@example.com and row 3 would be sent to user2@example.com

My Idea is to create an 'sendemail' function with the following parameters: data, to_email

Then iterate through the data frame rows passing the parameters to the for-loop.

Here's where I am:

import pandas as pd
from tabulate import tabulate
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

# import data into df
df1 = pd.read_excel("data.xlsx")

# define email function       
def sendemail(html, to_email):
   
    fromaddr = "from@email.com"
    toaddr = to_email
    msg = MIMEMultipart("alternative")
    msg["From"] = fromaddr
    msg["To"] = to_email
    msg["Subject"] = "new email"
    msg.add_header("reply-to", "user@email.com")

    body = MIMEText(html, "html")
    msg.attach(body)

    server = smtplib.SMTP("smtp.emailserver.com", 587)

    server.starttls()
      
    server.login(fromaddr, "pw")
    text = msg.as_string()
    server.sendmail(fromaddr, toaddr, text)

    server.quit()

#iterate trough rows and send email
for row in df1.itertuples(index=False):
    sendemail(df1.to_html(index=False), df1["email"])

I believe my error is passing the data into the for-loop. I am getting an error:

AttributeError: 'Series' object has no attribute 'encode'

Any assistance would be greatly appreciated!

Try to change your for loop to:

for row in df1.itertuples(index=False):
    sendemail(df1.to_html(index=False), row.email)

Here, instead of passing df1['email'] as a pandas Series to the sendmail() function where it requires a string for the 2nd argument, you access the row value under column 'email' by the syntax row.email , which is now an element (a string, in particular) and can be used directly in your sendmail() function.

An alternative way to access row.email is getattr(row, "email")

I used a different approach iterating through the email process to send it to each row level recipient. You can use a for loop and the zip() function to grab all necessary data. I used this on a relatively small data set and cannot speak to whether it performs well on large data sets.

for x,y,z,a in zip(fulldf['Employee Name'], fulldf['Store E-mail'], fulldf['E-mail'], fulldf['Date Hired']):
outlook = win32com.client.Dispatch('outlook.application')
mail = outlook.CreateItem(0)
mail.To = y
mail.CC = z
mail.Subject = 'Career Growth Conversation'
mail.HTMLBody = """\
    <html>
        <head></head>
        <body>
            <p>Congratulations – """+ x +" hire date: "+ a +""" is ready for a Career Growth Conversations!<br>
                
            </p>
        </body>
    </html>
    """
mail.Attachments.Add(r"")
mail.Send()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM