73885


Pythonで下記の条件でメールを送信したいです。

① csvの 特定の列 だけを抽出した pandasのDataFrame を作成する  
② 作成したDataFrameの 1行目と2行目(indexは0と1) に対して③~⑤の処理を行う  
③ 処理対象行の 各列の列名とデータを抽出してそれぞれに改行コードを付加し、連結する  
④ 抽出・連結した各列名＋データを、さらに改行コードで連結する  
⑤ 連結したデータをメール本文として挿入し、送信する

[code]

    ①CSV　順番
    A       B      C    D      
    test1 test2 test3  test4
    test5 test6 test7  test8
    
[/code]

現在のコード

[code]

    # coding:utf-8
    from datetime import datetime as dt, date, timedelta
    from pydomo.streams import UpdateMethod
    import csv
    import pandas as pd
    from email.mime.text import MIMEText
    import smtplib
    
    strDate = dt.now().strftime("%Y%m%d")
    
    filename = "test.csv"
    #csvデータをdfに読み込み。 
    df = pd.read_csv(filename,encoding='utf_8_sig')
    df_i = df.set_index("A","B","C")
    print(df_i)        
    
    account = "123@gmail.com"
    password = "123"
    
    to_email = "123@gmail.com"
    from_email = "123@gmail.com"
    
    subject = "テストメール"
    message = '\n'.join(df_i)  #←ここに"A","B","C"の特定の行を入れたい
    msg = MIMEText(message, "html")
    msg["Subject"] = subject
    msg["To"] = to_email
    msg["From"] = from_email
    
    server = smtplib.SMTP("smtp.gmail.com", 587)
    server.starttls()
    server.login(account, password)
    server.send_message(msg)
    server.quit()
    
    
[/code]

現在メールで送信した実行結果になります。  
1回目しかメール送信されないです。  
また結果には全てのヘッダが表示されます。

[code]

    A B C D
    
[/code]

実現したい実行結果メール送信1回  
※下記のように改行付きで入れたいです。

[code]

    A
    test1
    
    B
    test2
    
    C
    test3
    
[/code]

実現したい実行結果メール送信２回

[code]

    A
    test5
    
    B
    test6
    
    C
    test7
    
[/code]

どなたか分かる方がいれば教えていただきたいです。  
お手数ですが、よろしくお願いします。


CC BY-SA 4.0
2021-02-08T11:04:32.950
73865
2021-02-11T10:27:58.230
2021-02-11T10:27:58.230
3060
18859
question
python pandas csv
PythonでCSVから特定の列を読み込みメール送信


実現したい実行結果からすると、やりたいことは以下になると思われます。

① csvの **特定の列** だけを抽出した **pandasのDataFrame** を作成する  
② 作成したDataFrameの **1行目と2行目(indexは0と1)** に対して③~⑤の処理を行う  
③ 処理対象行の **各列の列名とデータを抽出してそれぞれに改行コードを付加し、連結する**  
④ 抽出・連結した各列名＋データを、さらに改行コードで連結する  
⑤ 連結したデータをメール本文として挿入し、送信する

* * *

① csvの **特定の列** だけを抽出した **pandasのDataFrame** を作成する

こちらの記事が参考になるでしょう。  
[pandasで特定の列を抽出する](https://qiita.com/guai3/items/f5ce0ab817f51e0a5d04)

質問のこの行を：

[code]

    df_i = df.set_index("A","B","C")
    
[/code]

こちらのように変更します：

[code]

    df_i = df[["A","B","C"]]
    
[/code]

* * *

② 作成したDataFrameの **1行目と2行目(indexは0と1)** に対して③~⑤の処理を行う

こちらのメソッドや関数を使います。  
[pandas.DataFrame.iloc](https://pandas.pydata.org/pandas-
docs/stable/reference/api/pandas.DataFrame.iloc.html)  
[4.3. range() 関数](https://docs.python.org/ja/3/tutorial/controlflow.html#the-
range-function)

* * *

③ 処理対象行の **各列の列名とデータを抽出してそれぞれに改行コードを付加し、連結する**

こちらのメソッドや記述方法を使います。  
[pandas.DataFrame.iteritems](https://pandas.pydata.org/pandas-
docs/stable/reference/api/pandas.DataFrame.iteritems.html)  
[5.1.3.
リストの内包表記](https://docs.python.org/ja/3/tutorial/datastructures.html#list-
comprehensions)  
[7.1.1.
フォーマット済み文字列リテラル](https://docs.python.org/ja/3.8/tutorial/inputoutput.html#formatted-
string-literals)

* * *

②③④を組み合わせると以下のような処理になります。  
(ここでは作成したデータを表示だけしています)

[code]

    for j in range(2):
        print('\n'.join([f"{column}\n{data}\n" for column,data in df_i.iloc[j].iteritems()]))
    
[/code]

* * *

質問のソースコード全体と組み合わせると、以下のようになるでしょう。  
`####` のある行が変更点です。

[code]

    # coding:utf-8
    from datetime import datetime as dt, date, timedelta
    from pydomo.streams import UpdateMethod
    import csv
    import pandas as pd
    from email.mime.text import MIMEText
    import smtplib
    
    strDate = dt.now().strftime("%Y%m%d")
    
    filename = "test.csv"
    #csvデータをdfに読み込み。 
    df = pd.read_csv(filename,encoding='utf_8_sig')
    #### df_i = df.set_index("A","B","C")
    df_i = df[["A","B","C"]] #### new!
    print(df_i)        
    
    account = "123@gmail.com"
    password = "123"
    
    to_email = "123@gmail.com"
    from_email = "123@gmail.com"
    
    for j in range(2): #### new! および以下をループとしてインデント
        subject = "テストメール"
        #### message = '\n'.join(df_i)  #←ここに"A","B","C"の特定の行を入れたい
        message = '\n'.join([f"{column}\n{data}\n" for column,data in df_i.iloc[j].iteritems()]) #### new!
        msg = MIMEText(message, "html")
        msg["Subject"] = subject
        msg["To"] = to_email
        msg["From"] = from_email
    
        server = smtplib.SMTP("smtp.gmail.com", 587)
        server.starttls()
        server.login(account, password)
        server.send_message(msg)
        server.quit()
    
[/code]

* * *

`msg = MIMEText(message, "html")`で改行されないのは、`message`の内容が`html`形式だと指定しているからですね。

2つ目のパラメータは`Content-type: text/****`の`****`の部分を指定していることになります。  
[class email.mime.text.MIMEText(_text, _subtype='plain', _charset=None, *,
policy=compat32)](https://docs.python.org/ja/3/library/email.mime.html#email.mime.text.MIMEText)

何も指定しないとデフォルトの`plain`であり、`Content-type:
text/plain`となり、テキストデータがそのまま使われることになります。

`text`を指定すると`Content-type: text/text`となり、[Media
Types](https://www.iana.org/assignments/media-types/media-
types.xhtml)に載っていないタイプになるので添付ファイル扱いになるのでしょう。


CC BY-SA 4.0
2021-02-09T09:01:16.960
73885
2021-02-09T11:40:20.283
2021-02-09T11:40:20.283
26370
26370
73865
answer