#Python3

CentOS6由于版本过老和源组织不当等原因,成功安装Python3和一些较新的依赖库是一件很幸运的事情。这里记录下遇到的报错和解决过程。
按照惯例,先记录一下报错内容,方便搜索引擎索引:

1
2
3
4
5
6
7
8
9
10
11
[[email protected] ~]# pip3 install --upgrade pip
pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/pip/
Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/pip/
Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/pip/
Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/pip/
Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/pip/
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
Requirement already up-to-date: pip in /usr/local/lib/python3.7/site-packages (19.0.3)
pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping

解决方法:

1.编译安装OpenSSL 1.0.2j版本并配置环境变量

下载OpenSSL源码包:

wget http://www.openssl.org/source/openssl-1.0.2j.tar.gz

解压缩,编译安装:

1
2
3
4
tar -zxvf openssl-1.0.2j.tar.gz
cd openssl-1.0.2j
./config --prefix=/usr/local/openssl-1.0.2j shared zlib
make && make install

2.编译安装Python3,使用自定义的OpenSSL

下载Python3.7.3源码包:

wget https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tgz

解压缩,编译安装:

1
2
3
tar -zxvf Python-3.7.3.tgz
cd Python-3.7.3
./configure

在这一步之后,先不要着急运行make命令。先修改Modules/Setup文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Socket module helper for socket(2)
#_socket socketmodule.c

# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
SSL=/usr/local/openssl-1.0.2j/ #取消这一行的注释,并将原来的/usr/local/ssl改为/usr/local/openssl-1.0.2j/
_ssl _ssl.c \ #取消这一行的注释
true-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ #取消这一行的注释
true-L$(SSL)/lib -lssl -lcrypto #取消这一行的注释

# The crypt module is now disabled by default because it breaks builds
# on many systems (where -lcrypt is needed), e.g. Linux (I believe).

#_crypt _cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems

修改完成以后,还需要创建两个指向动态链接库的软链接文件:

1
2
ln -s /usr/local/openssl-1.0.2j/lib/libssl.so.1.0.0 /usr/lib64/libssl.so.1.0.0
ln -s /usr/local/openssl-1.0.2j/lib/libcrypto.so.1.0.0 /usr/lib64/libcrypto.so.1.0.0

最后编译并安装:

1
make && make install

安装完成以后,再次运行pip3 install --upgrade pip,可以看到原先SSL连接报错的问题已经解决:

1
2
3
4
5
6
7
8
[[email protected] Python-3.7.3]# pip3 install --upgrade pip
Collecting pip
Using cached https://files.pythonhosted.org/packages/5c/e0/be401c003291b56efc55aeba6a80ab790d3d4cece2778288d65323009420/pip-19.1.1-py2.py3-none-any.whl
Installing collected packages: pip
Found existing installation: pip 19.0.3
Uninstalling pip-19.0.3:
Successfully uninstalled pip-19.0.3
Successfully installed pip-19.1.1

Python 3 通过SMTP库发送普通邮件(Through SSL)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/python3

import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

mail_host = "smtp.chorder.net"
mail_port = 994
mail_user = "[email protected]"
mail_pass = "password"

sender_name = "Example"
sender_account = '[email protected]'
receivers = ['[email protected]']
receiver_name = "Somebody"

subject = 'Mail Subject'
mail_msg = '''
<h1>This is a test main</h1>
<p>Some text</p>
'''


msgRoot = MIMEMultipart('related')
msgRoot['From'] = Header(sender_name, 'utf-8')
msgRoot['To'] = Header(receiver_name, 'utf-8')
msgRoot['Subject'] = Header(subject, 'utf-8')

msgAlternative = MIMEMultipart('alternative')
msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))

msgRoot.attach(msgAlternative)

try:
smtpObj = smtplib.SMTP_SSL( mail_host, mail_port )
#smtpObj.ehlo()
#smtpObj.set_debuglevel(1)
smtpObj.login( mail_user, mail_pass )
smtpObj.sendmail(sender_account, receivers, msgRoot.as_string())
print ("邮件发送成功")
except smtplib.SMTPException:
print ("Error: 无法发送邮件")

Python 3 通过SMTP库发送带图片的邮件(Through SSL)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/python3

import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

mail_host = "smtp.chorder.net"
mail_port = 994
mail_user = "[email protected]"
mail_pass = "password"

sender_name = "Example"
sender_account = '[email protected]'
receivers = ['[email protected]']
receiver_name = "Somebody"


subject = 'Mail Subject'
mail_msg = '''
<h1>This is a test main</h1>
<p>Some text</p>
<h2>Image</h2>
<p><img src="cid:image1"></p>
'''

# add image attachment
fp = open('test.png', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()

msgImage.add_header('Content-ID', '<image1>')

msgRoot = MIMEMultipart('related')

msgRoot['From'] = Header(sender_name, 'utf-8')
msgRoot['To'] = Header(receiver_name, 'utf-8')
msgRoot['Subject'] = Header(subject, 'utf-8')

msgAlternative = MIMEMultipart('alternative')
msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))

msgRoot.attach(msgAlternative)
msgRoot.attach(msgImage)

try:
smtpObj = smtplib.SMTP_SSL( mail_host, mail_port )
#smtpObj.ehlo()
#smtpObj.set_debuglevel(1)
smtpObj.login( mail_user, mail_pass )
smtpObj.sendmail(sender_account, receivers, msgRoot.as_string())
print ("邮件发送成功")
except smtplib.SMTPException:
print ("Error: 无法发送邮件")
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×