SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:748)
使用HTTP协议访问需要HTTPS协议访问的网页是,会返回302 Found
表示需要重定向到使用HTTPS访问
【SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:748)】socket使用HTTPS需要import ssl模块
import ssl
然后对socket对象进行包装
sock = ssl.wrap_socket(socket.socket())
此时出现错误
SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:748)
上网查找后发现自己没有修改访问对应的端口号,仍然用80端口号connect服务器,因此出错,需要将端口号改为https服务对应的443
下面为一个简单的通过socket方法实现get请求的代码,输出为访问的网页的response。此代码未根据指定的protocol分配对应端口号,有待修改。
# _*_ coding:utf-8 _*_
import socket
import ssl
"""
2017/02/16
作业 1资料:
在 Python3 中,bytes 和 str 的互相转换方式是
str.encode('utf-8')
bytes.decode('utf-8')send 函数的参数和 recv 函数的返回值都是 bytes 类型
其他请参考上课内容, 不懂在群里发问, 不要憋着
"""# 1
# 补全函数
def protocol_of_url(url):
'''
url 是字符串, 可能的值如下
'g.cn'
'g.cn/'
'g.cn:3000'
'g.cn:3000/search'
'http://g.cn'
'https://g.cn'
'http://g.cn/'返回代表协议的字符串, 'http' 或者 'https'
'''
parts = url.split('://')
if len(parts)>1:
return parts[0]
else:
return 'http'# 2
# 补全函数
def host_of_url(url):
'''
url 是字符串, 可能的值如下
'g.cn'
'g.cn/'
'g.cn:3000'
'g.cn:3000/search'
'http://g.cn'
'https://g.cn'
'http://g.cn/'返回代表主机的字符串, 比如 'g.cn'
'''
parts = url.split('://')
if len(parts)>1:
url = parts[1]
parts = url.split('/')url = parts[0]parts = url.split(':')
return parts[0]# 3
# 补全函数
def port_of_url(url):
'''
url 是字符串, 可能的值如下
'g.cn'
'g.cn/'
'g.cn:3000'
'g.cn:3000/search'
'http://g.cn'
'https://g.cn'
'http://g.cn/'返回代表端口的字符串, 比如 '80' 或者 '3000'
注意, 如上课资料所述, 80 是默认端口
'''
parts = url.split('://')
if len(parts)>1:
url = parts[1]
parts = url.split('/')url = parts[0]parts = url.split(':')
if len(parts)>1:
return parts[1]
else:
return '443'# 4
# 补全函数
def path_of_url(url):
'''
url 是字符串, 可能的值如下
'g.cn'
'g.cn/'
'g.cn:3000'
'g.cn:3000/search'
'http://g.cn'
'https://g.cn'
'http://g.cn/'返回代表路径的字符串, 比如 '/' 或者 '/search'
注意, 如上课资料所述, 当没有给出路径的时候, 默认路径是 '/'
'''
parts = url.split('://')
if len(parts)>1:
url = parts[1]
parts = url.split('/')
if len(parts) == 1:
return '/'
else:
return url.replace(parts[0],'')# 4
# 补全函数
def parsed_url(url):
'''
url 是字符串, 可能的值如下
'g.cn'
'g.cn/'
'g.cn:3000'
'g.cn:3000/search'
'http://g.cn'
'https://g.cn'
'http://g.cn/'
返回一个 tuple, 内容如下 (protocol, host, port, path)
'''
protocol = protocol_of_url(url)
host = host_of_url(url)
port = port_of_url(url)
path = path_of_url(url)
return (protocol, host, port, path)# 5
# 把向服务器发送 HTTP 请求并且获得数据这个过程封装成函数
# 定义如下
def get(url):
'''
本函数使用上课代码 client.py 中的方式使用 socket 连接服务器
获取服务器返回的数据并返回
注意, 返回的数据类型为 bytes
'''
protocol,host,port,path = parsed_url(url)sock = ssl.wrap_socket(socket.socket())
#sock = socket.socket()
sock.connect((host,int(port)))req = 'GET '+path+' HTTP/1.1\r\nHost: '+host+'\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0;
Win64;
x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;
q=0.9,image/webp,image/apng,*/*;
q=0.8,application/signed-exchange;
v=b3\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;
q=0.9\r\n\r\n'print(req)
sock.send(req.encode('utf-8'))buffer_size = 1024
response = ''
while True:
temp=sock.recv(buffer_size)
response = response + temp.decode('utf-8','ignore')
if len(temp) < buffer_size:
sock.close()
break
return response# 使用
def main():
url = 'https://movie.douban.com/top250'r = get(url)
print(r)if __name__ == '__main__':
main()
推荐阅读
- 【Tomcat源码阅读分享】—(5)Tomcat中的ClassLoader
- Centos|Centos 7 OpenSSL1.0.2K 动态库升级1.0.2U
- 说说SSL/TLS协议
- Mac 上制作 SSL 证书
- 通配符SSL证书选购攻略
- SSL: CERTIFICATE_VERIFY_FAILED
- SSL证书格式及转化方法
- Tengine + BabaSSL ,让国密更易用!
- ssl泛域名证书
- 次短路|SSLOJ 1297.GF打Dota