[Python之路] HTTP协议复习笔记
一、HTTP请求的直观了解
我们使用网络调试助手来模拟一个TCP Server,然后使用浏览器来访问对应的IP:Port。

启动后,我们使用谷歌浏览器来访问192.168.1.8:8080:
我们可以看到浏览器一直在等待服务器返回数据。
我们可以在 网络调试助手上看到接收到的HTTP请求:
GET / HTTP/1.1
Host: 192.168.1.8:
Connection: keep-alive
Cache-Control: max-age=
Upgrade-Insecure-Requests:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
解释:
1.GET是浏览器向服务器请求数据的一种方式,一般有GET和POST。
2.GET后面是一个空格(不可少)
3.空格后面的"/"表示请求的内容,如果我们请求时使用http://192.168.1.8:8080/index.html,则这里就是"/index.html"。
4."HTTP/1.1"是使用的HTTP协议版本,这里是1.1版本。
5.Host是请求的目的,即服务器地址。
6.Connection是链接的类别,keep-alive是长连接。
7.User-Agent是浏览器客户端的版本信息,普通用户使用标准浏览器访问时,都会有这个字段,如果没有该字段说明可能是爬虫程序。主要用于反爬虫。
8.Accept表示浏览器可以接受的数据类型。
9.Accept-Encoding表示浏览器可以接受的数据压缩格式(用于数据量比较大时,服务器进行压缩传输)。
10.Accept-Language表示浏览器可以接受的文本语言。
二、观察HTTP的响应头
我们使用谷歌浏览器访问百度首页,并打开F12来查看交互流程:

可以在其中找到我们需要的请求头、响应头信息:
请求头:
GET / HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Upgrade-Insecure-Requests:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: BAIDUID=F5E42E8A08547BB39711F21232455CB0:FG=1; BIDUPSID=F5E42E8A08547BB39711F21232455CB0; PSTM=1569579669; sugstore=1; MCITY=-75%3A; BD_UPN=12314753; H_PS_PSSID=1451_21123_29568_29221_26350; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; BD_CK_SAM=1; PSINO=7; BDSVRTM=137; BCLID=10618646423443952060; BDSFRCVID=g8COJeCmH6VwoRJwYAdxT9UxGmKK0gOTHllvFiwowP8T7G8VJeC6EG0Ptf8g0KubFTPRogKK0gOTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tJkD_I_hJKt3qn7I5KToh4Athxob2bbXHDo-LIvjfpOcOR5JhfA-3R-e046fXxobMNP8-4nTalvvhb3O3M7ShbKzMqJy-h8OQnvxVUQF5l8-sq0x0bOte-bQypoa0q3TLDOMahkM5h7xOKQoQlPK5JkgMx6MqpQJQeQ-5KQN3KJmfbL9bT3YjjISKx-_J6LeJRbP
响应头:
HTTP/1.1 OK
Bdpagetype:
Bdqid: 0xda48b61a00089ab4
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html
Cxy_all: baidu+1b1b86535b4f42dc5821baca812fd9c4
Date: Wed, Nov :: GMT
Expires: Wed, Nov :: GMT
Server: BWS/1.1
Set-Cookie: delPer=; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=; path=/
Set-Cookie: BD_HOME=; path=/
Set-Cookie: H_PS_PSSID=1451_21123_29568_29221_26350; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=
Traceid:
Vary: Accept-Encoding
X-Ua-Compatible: IE=Edge,chrome=
Transfer-Encoding: chunked
响应头解释:
1.HTTP/1.1 200 OK表示我们要请求的页面存在,可以成功返回。
2.Content-Encoding表示返回数据使用的压缩格式为gzip。
3.Date表示服务器当前的时间。
4.Content-Type表示返回数据的格式为text/html,这里也可能附带编码,例如utf-8。
5.Server表示服务器的名称和版本,这里的BWS/1.1是百度服务器的名称和版本。一般情况下为Apache、Nginx、Tengine等。
6.Set-Cookie见后面的详细解释...
Set-Cookie解释:
实际例子:假设我们使用JD搜索了"刮胡刀",为什么第二天我们再次打开JD的时候,就会给我们推送很多刮胡刀的广告。
1.第一次访问JD的时候,我们浏览器发送的请求头是很短的,只有最基本的一些信息,例如请求目录、浏览器版本等。
2.JD服务器再响应时,会检查请求头中是否存在Cookie,如果不存在,则会在响应头中使用Set-Cookie关键字传输一些信息给浏览器。例如上述响应头中的"Set-Cookie: H_PS_PSSID=1451_21123_29568_29221_26350; path=/; domain=.baidu.com"
3.Set-Cookie中的H_PS_PSSID、path和domain都是key,而后面的1451_***_26350等都是value。浏览器会将这些Cookie数据存在本地缓存中,domain表示下次访问关于baidu域名的网页时,将携带这些Cookie在请求头中。
4.第二天访问JD时,浏览器就将前一次存放的Cookie信息放在请求头中,传递给了服务器。其中的一些Cookie可能就是代表这个未登陆的用户ID(例如上述请求头中Cookie里的BAIDUID),服务器通过这个Cookie中携带的ID,就知道是昨天搜索刮胡刀的人,那么就可以给他推送刮胡刀广告。
三、查看响应体
在响应头后面空一行(浏览器就是根据这个空行来分隔响应头和响应体)之后,就是响应体。响应体主要是服务器返回的真正的页面信息,一般是html文本。
我们可以在F12中看到响应体:

四、使用python实现一个简单的静态Server
import socket leo_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 监听端口8900
leo_sock.bind(('192.168.1.8', 8900)) leo_sock.listen(5)
print('starting....')
conn, addr = leo_sock.accept()
print(conn)
print('client addr', addr)
print('ready to read msg')
client_msg = conn.recv(1024)
print('client msg: %s' % client_msg)
# 换行符是\r\n
reponse_msg = "HTTP/1.1 200 OK\r\n\r\n<h1>hahaha</h1>"
# TCP网络传输二进制数据
conn.send(reponse_msg.encode(encoding="utf-8")) # 关闭连接
conn.close()
# 关闭socket
leo_sock.close()
使用浏览器访问192.168.1.8:8900:

服务器成功返回了内容。
[Python之路] HTTP协议复习笔记的更多相关文章
- Python之路迭代器协议、for循环机制、三元运算、列表解析式、生成器
Python之路迭代器协议.for循环机制.三元运算.列表解析式.生成器 一.迭代器协议 a迭代的含义 迭代器即迭代的工具,那什么是迭代呢? #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的 ...
- python之路1
python之路 http协议 html HTML2 CSS选择器 CSS属性操作 CSS属性操作/下 JavaScript(js)/上 JavaScript的对象 JavaScript的对象/下 前 ...
- Python之路系列笔记
备注:本套笔记内容来源于互联网,只做学习使用,如有侵权请联系本笔记作者. 资料内容 Python之路(一)——Python 初识 Python之路(二)——基础语法 Python之路(三)——函数 P ...
- Python之路
Python学习之路 第一天 Python之路,Day1 - Python基础1介绍.基本语法.流程控制 第一天作业第二天 Python之路,Day2 - Pytho ...
- Java基础复习笔记系列 九 网络编程
Java基础复习笔记系列之 网络编程 学习资料参考: 1.http://www.icoolxue.com/ 2. 1.网络编程的基础概念. TCP/IP协议:Socket编程:IP地址. 中国和美国之 ...
- Python之路【第十七篇】:Django【进阶篇 】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
- Python之路【第九篇】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy
Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用 ...
- Python之路【第六篇】:socket
Python之路[第六篇]:socket Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字&quo ...
- Python之路【第十七篇】:Django之【进阶篇】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
随机推荐
- php导出excel方法: 所有语言通用
后端: //导出if($_GPC['export']==1){ $list_export = pdo_fetchall($sql.$where); include $this->templa ...
- SqlServer中插入数据后如何得到主键ID
使用@@IDENTITY 例如:insert into student(name,age) values('fanqi',23) select @@identity 使用 OUTPUT inserte ...
- 接口测试-免费开放的api
归纳一些不错的免费开放的api 1.Apizza免费开放的Api接口 链接: https://www.jianshu.com/p/e6f072839282 接口文档:https://www.apiop ...
- Codeforces 1194E. Count The Rectangles
传送门 看到 $n<=5000$,直接暴力枚举左右两条竖线 然后考虑怎么计算高度在某个范围内,左端点小于等于某个值,右端点大于等于某个值的横线数量 直接用权值树状数组维护当前高度在某个区间内的横 ...
- java中内部类
package com.xt.instanceoftest; import com.xt.instanceoftest.Body.Heart; public class StaticInnerClas ...
- js中的奇闻异事
- luogu P4437 [HNOI/AHOI2018]排列
luogu 问题本质是把\(a_i\)作为\(i\)的父亲,然后如果有环就不合法,否则每次要取数,要满足取之前他的父亲都被取过(父亲为0可以直接取),求最大价值 贪心想法显然是要把权值大的尽量放在后面 ...
- hadoop离线数据存储和挖掘架构
前序: 当你把你知道的东西,写下来,让人看明白是一种境界:当你能把自己写下来的东西给人讲明白,又是另一种境界.在这个过程中,我们都需要历练. 基于hadoop集群下海量离线数据存储和挖掘分析架构: 架 ...
- pycharm terminal打开在虚拟环境
pycharm调试是虚拟环境,terminal不是虚拟环境,搞了好久,原来需要激活一下 cd venv\Scripts> 去虚拟环境的Script目录下,运行activate.bat激活环境 ...
- se37 函数中的异常使用
一种是rase <exceptions> FUNCTION ztest. *"-------------------------------------------------- ...