# coding: utf-8
import socket
"""
1, recv 函数会返回接收的数据长度
如果返回值小于你给它的参数,说明已经接收完了所有数据
否则说明仍然有数据需要接收,你应该再次调用它来接收数据
用循环把它改成能正确接收所有数据
2, 把向服务器发送 HTTP 请求并且获得数据这个过程封装成函数
定义如下
def get(url):
url 格式为 http://g.cn/
返回的数据类型为 bytes
# 测试代码
url = 'http://movie.douban.com/top250'
response = get(url)
r = response.decode('utf-8')
print(r)
资料:
在 Python3 中,bytes 和 str 的互相转换方式是
str.encode('utf-8')
bytes.decode('utf-8')
send 函数的参数和 recv 函数的返回值都是 bytes 类型
"""
def get(url):
# '://' 定位 然后取第一个 / 的位置来切片
u = url.split('://')[1]
i = u.find('/')
host = u[:i]
path = u[i:]
port = 80
s = socket.socket()
# 因为下面的两个参数是默认值 所以可以不写
# s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# host port 都用变量表示 便于修改
s.connect((host, port))
request = 'GET {} HTTP/1.1\r\nhost:{}\r\n\r\n'.format(path, host)
# encoding 也是用变量装 原则就是尽量不要使用常量当参数 尤其是多次使用的相同值
encoding = 'utf-8'
s.send(request.encode(encoding))
response = b''
# 缓冲区大小要用两次 所以用变量装起来 便于修改编写
buffer_size = 1023
while True:
r = s.recv(buffer_size)
response += r
if len(r) < buffer_size:
break
return response.decode(encoding)
def main():
url = 'http://movie.douban.com/top250'
r = get(url)
print(r)
if __name__ == '__main__':
main()
# coding: utf-8
import socket
import ssl
"""
1,get 函数接受以下这种参数
g.cn
没有协议名的情况下默认用 HTTP
没有路径的情况下默认路径是 /
2,接收带端口的 URL
http://g.cn:80/
用 URL 中指定的端口来进行 socket 连接
"""
def parsed_url(url):
# 检查协议
if url[:7] == 'http://':
u = url.split('://')[1]
else:
# '://' 定位 然后取第一个 / 的位置来切片
u = url
# 检查默认 path
i = u.find('/')
if i == -1:
host = u
path = '/'
else:
host = u[:i]
path = u[i:]
# 检查端口
port = 80
if host.find(':') != -1:
h = host.split(':')
host = h[0]
port = int(h[1])
print(host, path, port)
return host, port, path
def get(url):
# 重复麻烦的掏粪工作 封装成函数
host, port, path = parsed_url(url)
s = socket.socket()
s.connect((host, port))
request = 'GET {} HTTP/1.1\r\nhost:{}\r\n\r\n'.format(path, host)
# encoding 也是用变量装 原则就是尽量不要使用常量当参数 尤其是多次使用的相同值
encoding = 'utf-8'
s.send(request.encode(encoding))
response = b''
# 缓冲区大小要用两次 所以用变量装起来 便于修改编写
buffer_size = 1023
while True:
r = s.recv(buffer_size)
response += r
if len(r) < buffer_size:
break
return response.decode(encoding)
def main():
url = 'http://movie.douban.com/top250'
r = get(url)
print(r)
def test():
# 默认协议和 path
url = 'g.cn'
r = get(url)
print(r)
# 带端口的主机
url = 'g.cn:80'
r = get(url)
print(r)
if __name__ == '__main__':
# main()
test()