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()


    推荐阅读