2008-12-08 42 views
32

Tôi có thể nhận và gửi email bằng python bằng cách nào? Một 'máy chủ thư' các loại.Nhận và gửi email bằng python

Tôi đang xem xét việc tạo ứng dụng nghe xem liệu ứng dụng có nhận được email được gửi tới [email protected] hay không và gửi email cho người gửi.

Bây giờ, tôi có thể làm điều này tất cả trong python, nó sẽ là tốt nhất để sử dụng thư viện bên thứ 3?

Trả lời

23

Dưới đây là một ví dụ rất đơn giản:

import smtplib 

server = 'mail.server.com' 
user = '' 
password = '' 

recipients = ['[email protected]', '[email protected]'] 
sender = '[email protected]' 
message = 'Hello World' 

session = smtplib.SMTP(server) 
# if your SMTP server doesn't need authentications, 
# you don't need the following line: 
session.login(user, password) 
session.sendmail(sender, recipients, message) 

Đối với tùy chọn hơn, xử lý lỗi, vv, nhìn vào smtplib module documentation.

+2

Đó bao gồm các phần việc gửi, nếu bạn có thể thêm một đoạn nhanh chóng để nghe cho thư mới bằng cách sử dụng mô-đun smptd đây sẽ là một lớn câu trả lời – Jay

+7

Chú giải này là rất xa từ một máy chủ thư điện tử thật sự bởi vì hầu hết các thực công việc (xếp hàng và truyền lại) được thực hiện bởi 'mail.server.com', không phải bởi chương trình Python. – bortzmeyer

+0

bạn nói đúng. nó rất xa một máy chủ thư thực sự. –

2

Có, bạn có thể thực hiện khá nhiều thứ với thư viện tích hợp sẵn. Thực hiện tìm kiếm ở đây để tìm các thẻ [python][email] và bạn sẽ thấy cách thực hiện.

4

poplib và smtplib sẽ là bạn của bạn khi phát triển ứng dụng của bạn.

6

Python có mô-đun SMTPD sẽ hữu ích cho bạn khi viết máy chủ. Có thể bạn cũng sẽ muốn mô-đun SMTP thực hiện gửi lại. Cả hai mô-đun đều nằm trong thư viện chuẩn ít nhất kể từ phiên bản 2.3.

2

Tùy thuộc vào số lượng thư bạn đang gửi, bạn có thể muốn xem xét sử dụng máy chủ thư thực như postifx hoặc sendmail (* nix systems) Cả hai chương trình đều có khả năng gửi thư đã nhận đến chương trình dựa trên địa chỉ email.

3

Phần gửi đã được bảo hiểm, cho nhận bạn có thể sử dụng pop hoặc imap

12

Tôi không nghĩ rằng nó sẽ là một ý tưởng tốt để viết một mail server thực bằng Python. Điều này chắc chắn có thể (xem bài viết của mcrute và Manuel Ceron để có chi tiết) nhưng nó là rất nhiều công việc khi bạn nghĩ về mọi thứ mà một máy chủ mail thực sự phải xử lý (xếp hàng, truyền lại, xử lý thư rác, vv).

Bạn nên giải thích chi tiết hơn những gì bạn cần. Nếu bạn chỉ muốn phản hồi email đến, tôi khuyên bạn nên định cấu hình máy chủ thư để gọi chương trình khi nhận được email. Chương trình này có thể làm những gì nó muốn (cập nhật một cơ sở dữ liệu, tạo một tập tin, nói chuyện với một chương trình Python khác).

Để gọi một chương trình tùy ý từ máy chủ mail, bạn có nhiều lựa chọn:

  1. Đối với sendmail và Postfix, một ~/.forward chứa "|/path/to/program"
  2. Nếu bạn sử dụng procmail, một hành động lộ trong |path/to/program
  3. Và chắc chắn nhiều người khác
+0

Tôi ghét khi mọi người downvote mà không cần thêm một bình luận. Vấn đề với câu trả lời của tôi là gì? – bortzmeyer

+0

Tôi không biết vấn đề là gì. Đó là câu trả lời cơ bản của tôi với nhiều chi tiết hơn. Tôi nghĩ đây là một giải pháp tốt. – epochwolf

+0

Trên thực tế, máy chủ smtpd của python khá tốt cho các ứng dụng nội bộ mà tôi đã sử dụng. SMTP thực sự không phải là tất cả những gì khó khăn để có được quyền, phần cứng là ghép kênh kết nối mạng. Không chắc tôi sẽ sử dụng nó để xử lý tải sản xuất "thực sự" mặc dù. – mcrute

12

Tìm thấy ví dụ hữu ích để đọc email bằng cách kết nối bằng IMAP:

Python — imaplib IMAP example with Gmail

import imaplib 
mail = imaplib.IMAP4_SSL('imap.gmail.com') 
mail.login('[email protected]', 'mypassword') 
mail.list() 
# Out: list of "folders" aka labels in gmail. 
mail.select("inbox") # connect to inbox. 
result, data = mail.search(None, "ALL") 

ids = data[0] # data is a list. 
id_list = ids.split() # ids is a space separated string 
latest_email_id = id_list[-1] # get the latest 

# fetch the email body (RFC822) for the given ID 
result, data = mail.fetch(latest_email_id, "(RFC822)") 

raw_email = data[0][1] # here's the body, which is raw text of the whole email 
# including headers and alternate payloads 
+0

Cảm ơn bạn đã liên kết, đây là một nguồn tài nguyên tuyệt vời. IMAP4 nâng cao hơn POP3, nhưng cung cấp nhiều khả năng hơn như có thể tìm kiếm thông qua các tiêu đề. – Joansy

1

Cách tốt nhất để làm điều này sẽ tạo ra một dịch vụ cửa sổ trong python mà nhận email bằng imaplib2

Dưới đây là một kịch bản mẫu python để làm same.You thể cài đặt tập lệnh này để chạy dưới dạng dịch vụ cửa sổ bằng cách chạy lệnh sau trên dòng lệnh "python THENAMEOFYOURSCRIPTFILE.py install".

import win32service 
import win32event 
import servicemanager 
import socket 
import imaplib2, time 
from threading import * 
import smtplib 
from email.MIMEMultipart import MIMEMultipart 
from email.MIMEText import MIMEText 
import datetime 
import email 

class Idler(object): 
    def __init__(self, conn): 
     self.thread = Thread(target=self.idle) 
     self.M = conn 
     self.event = Event() 

    def start(self): 
     self.thread.start() 

    def stop(self): 
     self.event.set() 

    def join(self): 
     self.thread.join() 

    def idle(self): 
     while True: 
      if self.event.isSet(): 
       return 
      self.needsync = False 
      def callback(args): 
       if not self.event.isSet(): 
        self.needsync = True 
        self.event.set() 
      self.M.idle(callback=callback) 
      self.event.wait() 
      if self.needsync: 
       self.event.clear() 
       self.dosync() 


    def dosync(self): 
     #DO SOMETHING HERE WHEN YOU RECEIVE YOUR EMAIL 

class AppServerSvc (win32serviceutil.ServiceFramework): 
    _svc_name_ = "receiveemail" 
    _svc_display_name_ = "receiveemail" 


    def __init__(self,args): 
     win32serviceutil.ServiceFramework.__init__(self,args) 
     self.hWaitStop = win32event.CreateEvent(None,0,0,None) 
     socket.setdefaulttimeout(60) 

    def SvcStop(self): 
     self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
     win32event.SetEvent(self.hWaitStop) 

    def SvcDoRun(self): 
     servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, 
           servicemanager.PYS_SERVICE_STARTED, 
           (self._svc_name_,'')) 
     self.main() 

    def main(self): 
     M = imaplib2.IMAP4_SSL("imap.gmail.com", 993) 
     M.login("YourID", "password") 
     M.select("INBOX") 
     idler = Idler(M) 
     idler.start() 
     while True: 
      time.sleep(1*60) 
     idler.stop() 
     idler.join() 
     M.close() 
     M.logout() 

if __name__ == '__main__': 
    win32serviceutil.HandleCommandLine(AppServerSvc) 
+0

Điều này trông không cần thiết phức tạp đối với mắt của tôi. Bạn có thể đạt được điều gì bằng cách biến dịch vụ này thành một dịch vụ Windows, thay vì chỉ giữ nó như một luồng hoặc quá trình độc lập (không có nền tảng)? – Ponkadoodle

+0

@Wallacoloo. Tôi đã viết điều này với hệ điều hành windows trong tâm trí. Một cái gì đó chạy cho bao giờ là tốt hơn chạy như một dịch vụ cửa sổ. Những lợi ích của một dịch vụ chắc chắn đáng giá thêm sự phức tạp. Ý kiến ​​khiêm tốn của tôi. – ambassallo

Các vấn đề liên quan