今天想在一个centos6.9的服务器上运行一段爬虫监控,因为需要python3的环境,于是就重新安装了python3(服务器默认是python2)。
【A】安装python3
1、安装依赖库
# yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel
2、编译安装python3,简要流程如下
# wget https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tgz
# mkdir -p /usr/local/python3
# tar -zxvf Python-3.8.2.tgz && cd Python-3.8.2 && ./configure –perfix=/usr/local/python3 && make && make install
# ln -s /usr/local/python3/bin/python3 /usr/bin/python3
# ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3
3、写入python3环境变量
# vi /etc/profile
在PATH中加入/usr/bin/python3,保存后执行
# source /etc/profile
【B】好事多磨
在安装python3后遇到一系列报错。表现如下:
1、想安装一些库,在pip3 install 指定了清华的源,居然报错(Can’t connect to HTTPS URL because the SSL module is not available),这个错误开始没有引起重视,我换了阿里云的源(-i http://mirrors.aliyun.com/pypi/simple/)解决了:
2、在执行我的脚本时候,发现自己requests.get一个https的地址居然也是上面这个报错,于是这个错误必须要解决了。
通过在网上找一些方案,这个错误表现为在python3的环境下imoprt ssl出错,主要错误为:No module named ‘_ssl’
根据自己解决该问题的经验来看,实际上是系统的openssl版本过低,执行如下命令,可发现openssl版本太低,应该是centos6过老
# rpm -qa openssl
# openssl version
解决方案为两步骤:
(1)升级openssl
(2)重新编译安装python3.8.2
【第一步:升级openssl】
备份老版本的openssl
# which openssl
/usr/bin/openssl
# mv /usr/bin/openssl /usr/bin/openssl.old
# rm -rf /etc/ssl/
安装新版本openssl
# wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz (该版本2020年4月21日发布)
# tar -zxvf openssl-1.1.1g.tar.gz && cd openssl-1.1.1g
# ./config shared –openssldir=/usr/local/openssl –prefix=/usr/local/openssl
# make && make install
# ln -s /usr/local/openssl/bin/openssl /usr/local/bin/openssl
# cp -r /usr/local/bin/openssl /usr/bin/
# openssl version -a
如下就更新完毕了
【第二步:重新编译python3.8.2】
进入python3的源代码目录
# ./configure prefix=/usr/local/python3 –with-openssl=/usr/local/openssl/
在执行配置过程中,又出来一个错误
In function ‘_ssl_configure_hostname’:
error: implicit declaration of function ‘SSL_get0_param’
error: implicit declaration of function ‘X509_VERIFY_PARAM_set1_host’
……
make: *** [Modules/_ssl.o] Error 1
经过查询,该错误是python3配置中未开启_ssl模块,这个真是有点奇怪了。解决方案如下:
进入python3的源码目录
# vi Python-3.8.2/Modules/Setup
按/查找_ssl,将如下部分代码的注释#去掉,wq保存,注意浅绿色部分的配置一定要是自己的openssl执行文件路径(默认是/usr/local/ssl,我这里修改了)
# 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
_ssl _ssl.c \
-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
-L$(SSL)/lib -lssl -lcrypto
上述操作后再执行make && make install
在python3重新编译安装完毕后,访问https站点的问题就解决了。
【最后一个坑】
python的requests库,在带cookie时候(我的cookie是附带在header中的字符串形式),在linux上请求不到数据,我感到很奇怪,在windows上是正常执行的。后面测试发现是使用了requests的session方法:
解决方案为:
老代码:
se=requests.session()
r = se.get(url,headers=header,timeout=6,verify=False)
新代码:
r = requests.get(url,headers=header,timeout=6,verify=False)
简单说来就是不使用requests的session方法,具体原因还不清楚,后面再研究了。