Kode ini berfungsi dan mengirimkan saya email:
import smtplib
#SERVER = "localhost"
FROM = '[email protected]'
TO = ["[email protected]"] # must be a list
SUBJECT = "Hello!"
TEXT = "This message was sent with Python's smtplib."
# Prepare actual message
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
# Send the mail
server = smtplib.SMTP('myserver')
server.sendmail(FROM, TO, message)
server.quit()
Namun jika saya mencoba untuk membungkusnya dalam fungsi seperti ini:
def sendMail(FROM,TO,SUBJECT,TEXT,SERVER):
import smtplib
"""this is some test documentation in the function"""
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
# Send the mail
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()
dan menyebutnya saya mendapatkan kesalahan berikut:
Traceback (most recent call last):
File "C:/Python31/mailtest1.py", line 8, in <module>
sendmail.sendMail(sender,recipients,subject,body,server)
File "C:/Python31\sendmail.py", line 13, in sendMail
server.sendmail(FROM, TO, message)
File "C:\Python31\lib\smtplib.py", line 720, in sendmail
self.rset()
File "C:\Python31\lib\smtplib.py", line 444, in rset
return self.docmd("rset")
File "C:\Python31\lib\smtplib.py", line 368, in docmd
return self.getreply()
File "C:\Python31\lib\smtplib.py", line 345, in getreply
raise SMTPServerDisconnected("Connection unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly closed
Adakah yang bisa membantu saya memahami mengapa?
Jawaban:
Saya sarankan Anda menggunakan paket standar
email
dansmtplib
bersama - sama mengirim email. Silakan lihat contoh berikut (direproduksi dari dokumentasi Python ). Perhatikan bahwa jika Anda mengikuti pendekatan ini, tugas "sederhana" memang sederhana, dan tugas yang lebih kompleks (seperti melampirkan objek biner atau mengirim pesan multipart HTML / polos) diselesaikan dengan sangat cepat.Untuk mengirim email ke beberapa tujuan, Anda juga dapat mengikuti contoh dalam dokumentasi Python :
Seperti yang Anda lihat, header
To
diMIMEText
objek harus berupa string yang terdiri dari alamat email yang dipisahkan oleh koma. Di sisi lain, argumen kedua kesendmail
fungsi harus berupa daftar string (setiap string adalah alamat email).Jadi, jika Anda memiliki tiga alamat email:
[email protected]
,[email protected]
, dan[email protected]
, dapat Anda lakukan sebagai berikut (bagian jelas dihilangkan):yang
",".join(to)
bagian membuat string tunggal dari daftar, dipisahkan dengan koma.Dari pertanyaan Anda, saya berpendapat bahwa Anda belum melalui tutorial Python - itu HARUS jika Anda ingin mendapatkan di mana saja di Python - dokumentasi sebagian besar sangat baik untuk perpustakaan standar.
sumber
", ".join(["[email protected]", "[email protected]"])
with
:with open(textfile, 'rb') as fp:
. Tutup eksplisit dapat dijatuhkan, karenawith
blok akan menutup file meskipun terjadi kesalahan di dalamnya.Nah, Anda ingin memiliki jawaban yang mutakhir dan modern.
Inilah jawaban saya:
Ketika saya perlu mengirimkan python, saya menggunakan mailgun API yang banyak sakit kepala dengan mengirim surat diurutkan. Mereka memiliki aplikasi / api hebat yang memungkinkan Anda mengirim 10.000 email per bulan secara gratis.
Mengirim email akan seperti ini:
Anda juga dapat melacak acara dan banyak lagi, lihat panduan mulai cepat .
Saya harap Anda menemukan ini berguna!
sumber
Saya ingin membantu Anda mengirim email dengan menyarankan paket yagmail (saya pengelola, maaf untuk iklannya, tetapi saya merasa ini benar-benar dapat membantu!).
Seluruh kode untuk Anda adalah:
Perhatikan bahwa saya memberikan default untuk semua argumen, misalnya jika Anda ingin mengirim sendiri, Anda dapat menghilangkan
TO
, jika Anda tidak menginginkan subjek, Anda juga dapat menghilangkannya.Selain itu, tujuannya juga untuk membuatnya sangat mudah untuk melampirkan kode html atau gambar (dan file lainnya).
Di mana Anda meletakkan konten, Anda dapat melakukan sesuatu seperti:
Wow, betapa mudahnya mengirim lampiran! Ini akan memakan waktu 20 baris tanpa yagmail;)
Juga, jika Anda mengaturnya sekali, Anda tidak perlu memasukkan kata sandi lagi (dan menyimpannya dengan aman). Dalam kasus Anda, Anda dapat melakukan sesuatu seperti:
yang jauh lebih ringkas!
Saya mengundang Anda untuk melihat github atau menginstalnya secara langsung
pip install yagmail
.sumber
yagmail
selain gmail? Saya mencoba menggunakan untuk server SMTP saya sendiri.Attachment
kelas; itu masih hal yang sama. Jika mereka dapat mengubah kode Anda, maka mereka dapat tetap melakukan apa pun yang mereka inginkan (dengan / tanpa root, itu sama dengan pengiriman email wrt). Bagi saya ini seperti "khasnya nyaman / magis sehingga pasti kurang aman". Saya ingin tahu apa ancaman nyata yang Anda lihat?Ada masalah lekukan. Kode di bawah ini akan berfungsi:
sumber
SERVER
variabel yang diteruskan ke fungsi adalah kredensial pengguna.email
Pustaka Python melakukan ini dengan cukup baik (terutama sejak 3,6) meskipun masih membutuhkan pemahaman tentang apa yang Anda lakukan.Berikut adalah contoh tentang Python
3.x
, jauh lebih sederhana daripada2.x
:panggil fungsi ini:
di bawah ini hanya untuk pengguna China:
Jika Anda menggunakan 126/163, 网易 邮箱, Anda perlu mengatur "客户 端 授权 密码", seperti di bawah ini:
ref: https://stackoverflow.com/a/41470149/2803344 https://docs.python.org/3/library/email.examples.html#email-examples
sumber
Saat indentasi kode Anda dalam fungsi (yang ok), Anda juga membuat indentasi baris string pesan mentah. Tetapi ruang putih terdepan menyiratkan pelipatan (penggabungan) dari baris header, seperti yang dijelaskan dalam bagian 2.2.3 dan 3.2.3 dari RFC 2822 - Format Pesan Internet :
Dalam bentuk fungsi
sendmail
panggilan Anda , semua saluran dimulai dengan spasi putih dan "terbuka" (digabungkan) dan Anda mencoba mengirimSelain yang disarankan oleh pikiran kita,
smtplib
tidak akan memahamiTo:
danSubject:
header lagi, karena nama-nama ini hanya dikenali pada awal baris. Sebaliknyasmtplib
akan menerima alamat email pengirim yang sangat panjang:Ini tidak akan berhasil dan begitu pula Pengecualian Anda.
Solusinya sederhana: Pertahankan
message
string seperti sebelumnya. Ini dapat dilakukan oleh suatu fungsi (seperti yang disarankan Zeeshan) atau langsung dalam kode sumber:Sekarang unfolding tidak terjadi dan Anda kirim
mana yang berhasil dan apa yang dilakukan oleh kode lama Anda.
Perhatikan bahwa saya juga menjaga garis kosong antara header dan tubuh untuk mengakomodasi bagian 3.5 dari RFC (yang diperlukan) dan meletakkan menyertakan di luar fungsi sesuai dengan panduan gaya Python PEP-0008 (yang opsional).
sumber
Mungkin menempatkan tab ke pesan Anda. Cetak pesan sebelum Anda meneruskannya ke sendMail.
sumber
Pastikan Anda telah memberikan izin kepada Pengirim dan Penerima untuk mengirim email dan menerima email dari sumber tidak dikenal (Sumber Eksternal) di Akun Email.
sumber
msg
bukan pesan SMTP yang valid, dan hanya akan tampak menghilang ke eter jika server email Anda menerimanya.Kupikir aku akan memasukkan dua bitku di sini karena aku baru saja menemukan cara kerjanya.
Tampaknya Anda tidak memiliki port yang ditentukan pada pengaturan koneksi SERVER Anda, ini mempengaruhi saya sedikit ketika saya mencoba untuk terhubung ke server SMTP saya yang tidak menggunakan port default: 25.
Menurut dokumen smtplib.SMTP, permintaan / respons ehlo atau helo Anda secara otomatis akan dijaga, jadi Anda tidak perlu khawatir tentang ini (tetapi mungkin sesuatu untuk mengonfirmasi jika semuanya gagal).
Hal lain yang perlu Anda tanyakan adalah apakah Anda mengizinkan koneksi SMTP di server SMTP Anda sendiri? Untuk beberapa situs seperti GMAIL dan ZOHO Anda harus benar-benar masuk dan mengaktifkan koneksi IMAP dalam akun email. Server email Anda mungkin tidak mengizinkan koneksi SMTP yang tidak datang dari 'localhost' mungkin? Sesuatu untuk dilihat.
Yang terakhir adalah Anda mungkin ingin mencoba dan memulai koneksi pada TLS. Sebagian besar server sekarang memerlukan jenis otentikasi ini.
Anda akan melihat saya memasukkan dua bidang KE ke dalam email saya. Item kamus msg ['TO'] dan msg ['FROM'] memungkinkan informasi yang benar muncul di tajuk email itu sendiri, yang dilihat orang di ujung penerima email di bidang Ke / Dari (Anda bahkan mungkin dapat menambahkan bidang Balas Ke di sini. Bidang TO dan FROM sendiri adalah yang diperlukan server. Saya tahu saya pernah mendengar beberapa server email menolak email jika mereka tidak memiliki header email yang tepat.
Ini adalah kode yang saya gunakan, dalam suatu fungsi, yang berfungsi bagi saya untuk mengirim email isi file * .txt menggunakan komputer lokal saya dan server SMTP jarak jauh (ZOHO seperti yang ditunjukkan):
sumber
Perlu dicatat bahwa modul SMTP mendukung manajer konteks sehingga tidak perlu secara manual memanggil berhenti (), ini akan menjamin itu selalu dipanggil bahkan jika ada pengecualian.
sumber
Sejauh menyangkut kode Anda, tampaknya tidak ada yang salah secara mendasar kecuali bahwa, Anda tidak jelas bagaimana Anda sebenarnya memanggil fungsi itu. Yang bisa saya pikirkan adalah bahwa ketika server Anda tidak merespons maka Anda akan mendapatkan kesalahan SMTPServerDisconnected ini. Jika Anda mencari fungsi getreply () di smtplib (kutipan di bawah), Anda akan mendapatkan ide.
periksa contoh di https://github.com/rreddy80/sendEmails/blob/master/sendEmailAttachments.py yang juga menggunakan panggilan fungsi untuk mengirim email, jika itu yang Anda coba lakukan (pendekatan KERING).
sumber