introduction
In automated office and system development, email sending is a common requirement. Whether it is sending notifications, reports, or transferring files, Python's smtplib and email libraries provide convenient implementation methods. However, in actual development, developers often encounter various SMTP errors, such as (-1, b'\x00\x00\x00'), AttributeError('characters_writen'), etc., and these problems are often helpless.
This article will start from actual cases, analyze common SMTP errors, and provide complete solutions to help developers quickly locate and solve problems. At the same time, we will also optimize the code to make it more robust and easier to maintain.
1. Problem background
In Python, usesmtplib
When sending emails, you usually encounter two types of problems:
- Connection and authentication issues (such as error in authorization code, SMTP server refuses to connect)
- Data encoding and protocol issues (such as SSL/TLS handshake failure, attachment encoding error)
Here is a typical mail sending code that may trigger the above error:
import smtplib from import MIMEText from import MIMEMultipart from import MIMEApplication import os import logging logger = (__name__) def send_email_with_attachment(filepath, receiver_email): sender_email = "your_email@" password = "your_authorization_code" # QQ Email Authorization Code smtp_server = "" smtp_port = 465 # QQ mailbox SSL port msg = MIMEMultipart() msg['From'] = sender_email msg['To'] = receiver_email msg['Subject'] = "Notification of File Processing Results" # Email text (MIMEText("Please check the attachment", 'plain')) # Add attachment try: with open(filepath, "rb") as f: part = MIMEApplication((), Name=(filepath)) part['Content-Disposition'] = f'attachment; filename="{(filepath)}"' (part) except FileNotFoundError: ("The attachment file does not exist") return False # Send email try: with smtplib.SMTP_SSL(smtp_server, smtp_port) as server: (sender_email, password) (sender_email, receiver_email, msg.as_string()) return True except Exception as e: (f"Failed to send an email: {e}", exc_info=True) return False
When running this code, you may encounter the following error:
2. Common errors and solutions
Error 1: SMTPResponseException: (-1, b'\x00\x00\x00')
Cause of error
- The authorization code is incorrect or expired.
- An abnormal login was detected by the SMTP server (such as QQ mailbox) and the connection was refused.
- The network or firewall intercepts SMTP requests.
Solution
1. Check the authorization code
Log in to QQ mailbox → Settings → Account → Generate a new authorization code and replace password in the code.
2. Replace the SMTP port (recommended to use 587+TLS)
QQ mailbox supports 465 (SSL) and 587 (TLS), the latter is more stable:
smtp_port = 587 # Use TLS port insteadwith (smtp_server, smtp_port) as server: () # Enable TLS encryption (sender_email, password)
3. Check the network environment
Turn off the firewall or switch the network (such as using a phone hotspot test).
Error 2: AttributeError('characters_writen')
Cause of error
- Compatibility issues with Python 3.10+ with SMTP_SSL.
- The SSL/TLS handshake failed, probably due to the OpenSSL version mismatch.
Solution
1. Use starttls() instead (recommended)
Avoid using SMTP_SSL, use SMTP + starttls() instead:
with (smtp_server, 587) as server: () # Explicitly enable TLS (sender_email, password)
2. Downgrade Python or upgrade dependency library
If the error is still reported, try downgrading to Python 3.9, or update pyopenssl:
pip install --upgrade pyopenssl
3. Optimized email sending code
Combining the above solution, the optimized code is as follows:
import smtplib from import MIMEText from import MIMEMultipart from import MIMEApplication import os import logging import base64 logger = (__name__) def send_email_with_attachment(filepath, receiver_email): """Send emails with attachments (support QQ mailboxes)""" sender_email = "your_email@" password = "your_authorization_code" # Replace with the latest authorization code smtp_server = "" smtp_port = 587 # Use TLS port # Check if the attachment exists if not (filepath): (f"The attachment file does not exist: {filepath}") return False # Create email content msg = MIMEMultipart() msg['From'] = sender_email msg['To'] = receiver_email msg['Subject'] = "Notification of File Processing Results" (MIMEText("Please check the attachment", 'plain')) # Add attachment try: with open(filepath, "rb") as f: part = MIMEApplication((), Name=(filepath)) part['Content-Disposition'] = f'attachment; filename="{(filepath)}"' (part) except Exception as e: (f"Accessories failed to process: {e}") return False # Send emails (using TLS) try: with (smtp_server, smtp_port) as server: () # Enable TLS encryption (sender_email, password) (sender_email, receiver_email, msg.as_string()) ("Email sent successfully") return True except as e: (f"SMTPmistake: {e}") except Exception as e: (f"未知mistake: {e}", exc_info=True) return False
Optimization point
1. More robust exception handling
Distinguish between SMTPException and other exceptions to facilitate troubleshooting.
2. Pre-check attachments
Verify that the attachment exists before sending.
3. Logging
Use logging to record detailed error information.
4. SMTP debugging skills
Manually test SMTP connection
Use the openssl command line tool to test whether the SMTP service is available:
openssl s_client -connect :587 -starttls smtp -crlf
Enter the following command (replace with your email and authorization code):
EHLO test
AUTH LOGIN
<base64-encoded mailbox> # Example: echo -n "your_email@" | base64
<base64 encoded authorization code>
QUIT
If 235 Authentication successful is returned, it means that the SMTP configuration is correct.
Check the firewall
On Windows, run the following command to send the SMTP port:
netsh advfirewall firewall add rule name="SMTP" dir=in action=allow protocol=TCP localport=587
5. Summary and best practices
FAQ Summary
mistake | reason | Solution |
---|---|---|
(-1, b'\x00\x00\x00') |
Authorization code error/SMTP rejection | Update the authorization code and use it insteadstarttls()
|
AttributeError('characters_written') |
Python 3.10+ compatibility issues | Downgrade Python or use it insteadSMTP + starttls()
|
SSL: WRONG_VERSION_NUMBER |
SSL/TLS configuration error | usestarttls() + Port 587 |
Best Practices
- Use TLS (port 587) instead of SSL (port 465) for better compatibility.
- Update authorization code regularly to avoid sending failure due to expiration.
- Add log records to facilitate troubleshooting.
- Manually test the SMTP connection to ensure the server is available.
Through the analysis and optimization of this article, you should be able to solve most Python email sending problems. If your scenario involves more complex requirements (such as batch sending, HTML mail), you can further expand the code logic.
This is the article about the detailed explanation of the common problems and solutions for Python using SMTP to send emails. For more related content on Python SMTP to send emails, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!