以网址http://movie.douban.com/top250为例
一个url网址由以下几个部分组成:
协议:http,https等
主机:host,movie.douban.com
也就是IP地址,只不过IP是由一串数字组成,比较难记,所以用规律的好记的域名来代替。可以在命令行中通过Ping movie.douban.com 获取对应的IP为211.147.4.32。
端口:port,同一个IP地址下有不同的应用,操作系统会分发不同的端口给不同的请求,完成与服务器端的通信。比如QQ与火狐都发送了请求,需要不同端口来实现数据传输。可参考同一栋楼的不同门牌号,邮递员通过门牌号正确派送。
路径:path, 同一个网站下不同的页面,需要通过路径来获取需要的html页面。
以下代码手写了一个简易浏览器,其中get函数实现了url的解析,通过host和port进行socket进行连接与通信。具体代码如下:
# coding: utf-8
import socket
import ssl
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()