文章目录
- [深入理解 HTTP/HTTPS 协议、接口交互、会话与请求参数处理机制](#深入理解 HTTP/HTTPS 协议、接口交互、会话与请求参数处理机制)
-
- [1. HTTP 是什么?](#1. HTTP 是什么?)
- [2. 一个 HTTP 请求由哪些部分组成?](#2. 一个 HTTP 请求由哪些部分组成?)
- [3. HTTP 请求方法](#3. HTTP 请求方法)
- [4. HTTP 状态码](#4. HTTP 状态码)
- [5. HTTP Headers 请求头](#5. HTTP Headers 请求头)
- [6. 接口交互流程](#6. 接口交互流程)
- [7. Cookie 与 Session](#7. Cookie 与 Session)
- [8. Token 认证机制](#8. Token 认证机制)
-
- [Token 示例](#Token 示例)
- [9. HTTPS 是什么?](#9. HTTPS 是什么?)
- [10. HTTPS 握手流程](#10. HTTPS 握手流程)
- [11. TLS握手和TLS指纹](#11. TLS握手和TLS指纹)
-
- 关系图
- TLS指纹从哪里来?
- [为什么浏览器和 requests 指纹不同?](#为什么浏览器和 requests 指纹不同?)
- 为什么会403?
- TLS握手中的哪些字段参与指纹?
深入理解 HTTP/HTTPS 协议、接口交互、会话与请求参数处理机制
1. HTTP 是什么?
HTTP 是客户端和服务端之间进行数据交换的协议。
在爬虫中,最常见的流程是:
text
客户端/爬虫程序 → 发送请求 → 服务端
客户端/爬虫程序 ← 返回响应 ← 服务端
例如访问一个接口:
python
import requests
url = "https://example.com/api/list"
resp = requests.get(url)
print(resp.text)
本质上就是模拟浏览器向服务器发送 HTTP 请求。
2. 一个 HTTP 请求由哪些部分组成?
一个完整请求通常包括:
text
请求方法 Method
请求地址 URL
请求头 Headers
请求参数 Params / Body
Cookie
例如:
python
import requests
url = "https://example.com/api/search"
headers = {
"User-Agent": "Mozilla/5.0",
"Referer": "https://example.com",
"Accept": "application/json",
}
params = {
"keyword": "python",
"page": 1
}
cookies = {
"sessionid": "xxx"
}
resp = requests.get(
url,
headers=headers,
params=params,
cookies=cookies
)
print(resp.json())
3. HTTP 请求方法
GET
常用于查询数据。
python
requests.get(url, params={"page": 1})
最终 URL 类似:
text
https://example.com/list?page=1
特点:
- 参数在 URL 上
- 适合查询
- 容易被缓存
- 参数长度有限制
POST
常用于提交数据。
python
requests.post(url, data={"username": "admin"})
特点:
- 参数一般放在请求体 Body 中
- 适合登录、提交表单、搜索接口
- 参数不直接显示在 URL 中
PUT / PATCH
常用于更新数据。
DELETE
常用于删除数据。
4. HTTP 状态码
爬虫工程师必须熟悉状态码。
2xx:成功
text
200 OK
201 Created
204 No Content
3xx:重定向
text
301 永久重定向
302 临时重定向
304 使用缓存
爬虫中遇到 302,常见于:
- 未登录跳转
- Cookie 失效
- 风控跳转
- 地区跳转
4xx:客户端问题
text
400 参数错误
401 未登录
403 禁止访问
404 页面不存在
429 请求过快
爬虫常见:
text
403:Header、Cookie、Referer、签名、IP 有问题
429:请求频率太高
5xx:服务端问题
text
500 服务端异常
502 网关错误
503 服务不可用
504 超时
爬虫处理方式:
- 重试
- 降低并发
- 更换代理
- 增加超时控制
5. HTTP Headers 请求头
Headers 是爬虫中非常重要的一部分。
常见请求头:
python
headers = {
"User-Agent": "Mozilla/5.0",
"Accept": "application/json, text/plain, */*",
"Accept-Language": "zh-CN,zh;q=0.9",
"Referer": "https://example.com/",
"Origin": "https://example.com",
"Content-Type": "application/json",
"Authorization": "Bearer token_xxx"
}
User-Agent
标识客户端类型。
服务器通过 User-Agent 判断当前访问者使用的是:
text
Chrome
Firefox
Edge
Safari
Android
iPhone
Python Requests
如果不设置或使用默认值,容易被识别为爬虫请求。
python
headers = {
"User-Agent": "Mozilla/5.0"
}
常见浏览器UA:
python
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
}
面试追问:
- User-Agent 能否完全伪装浏览器?
- 为什么设置了 Chrome UA 仍然返回 403?
参考答案:
不能。
User-Agent 只能伪装 HTTP 层信息,网站还会检测:
text
Cookie
TLS指纹(JA3)
HTTP2特征
浏览器环境
Canvas指纹
WebGL指纹
因此仅修改 User-Agent 无法完全绕过风控。
Accept
表示客户端能够接受的响应内容类型。
服务器会根据 Accept 返回对应格式的数据。
python
headers = {
"Accept": "application/json, text/plain, */*"
}
表示:
text
优先接受:
application/json
其次:
text/plain
最后:
任意格式
常见类型:
text
application/json JSON数据
text/html HTML页面
text/plain 纯文本
image/png 图片
*/* 任意格式
Accept-Language
表示客户端期望使用的语言。
服务器可能根据该字段返回不同语言内容。
python
headers = {
"Accept-Language": "zh-CN,zh;q=0.9"
}
含义:
text
优先:
简体中文(中国)
其次:
任意中文
常见值:
text
zh-CN 简体中文
zh-TW 繁体中文
en-US 美式英语
ja-JP 日语
ko-KR 韩语
示例:
http
Accept-Language: en-US,en;q=0.9
返回:
json
{
"title":"iPhone"
}
Referer
表示当前请求来源页面。
服务器可以通过 Referer 判断:
text
请求从哪个页面发起
是否来自本站
是否存在盗链行为
例如:
python
headers = {
"Referer": "https://example.com/search"
}
浏览器访问流程:
text
首页
↓
搜索页
↓
详情页接口
对应 Referer:
http
Referer: https://example.com/search
很多网站会校验 Referer。
如果缺失:
http
Referer:
可能返回:
http
403 Forbidden
Origin
常用于跨域请求校验。
python
headers = {
"Origin": "https://example.com"
}
Content-Type
表示请求体格式。
常见:
text
application/json
application/x-www-form-urlencoded
multipart/form-data
text/plain
6. 接口交互流程
以登录接口为例:
text
1. 访问首页
2. 获取 Cookie
3. 获取 csrf_token
4. 提交账号密码
5. 获取登录态
6. 携带 Cookie / Token 请求数据接口
代码示例:
python
import requests
session = requests.Session()
# 1. 访问首页,拿初始 Cookie
session.get("https://example.com")
# 2. 登录
login_url = "https://example.com/api/login"
data = {
"username": "admin",
"password": "123456"
}
resp = session.post(login_url, json=data)
# 3. 后续请求自动携带 Cookie
data_url = "https://example.com/api/user/info"
resp2 = session.get(data_url)
print(resp2.text)
7. Cookie 与 Session
Cookie
Cookie 存储在客户端。
例如:
text
Set-Cookie: sessionid=abc123
下次请求会携带:
text
Cookie: sessionid=abc123
Session
Session 存储在服务端。
流程:
text
用户登录成功
服务端生成 sessionid
服务端把 sessionid 返回给客户端
客户端后续请求携带 sessionid
服务端根据 sessionid 判断用户身份
Python 中保持会话
python
import requests
s = requests.Session()
s.get("https://example.com")
s.post("https://example.com/login", data={
"username": "admin",
"password": "123456"
})
r = s.get("https://example.com/user")
print(r.text)
requests.Session() 可以自动维护 Cookie。
8. Token 认证机制
现在很多接口使用 Token,而不是传统 Cookie。
常见请求头:
python
headers = {
"Authorization": "Bearer eyJhbGciOi..."
}
流程:
text
1. 登录
2. 服务端返回 access_token
3. 后续接口 Header 中携带 Authorization
4. Token 过期后使用 refresh_token 刷新
Token 示例
python
import requests
login_resp = requests.post(
"https://example.com/api/login",
json={
"username": "admin",
"password": "123456"
}
)
token = login_resp.json()["access_token"]
headers = {
"Authorization": f"Bearer {token}"
}
resp = requests.get(
"https://example.com/api/user/info",
headers=headers
)
print(resp.json())
9. HTTPS 是什么?
HTTPS = HTTP + TLS/SSL 加密。
HTTP 明文传输,HTTPS 加密传输。
HTTPS 主要解决三个问题:
text
加密:防止内容被窃听
认证:确认访问的是目标服务器
完整性:防止数据被篡改
10. HTTPS 握手流程
简化流程:
text
1. 客户端发送 Client Hello
2. 服务端返回 Server Hello
3. 服务端下发证书
4. 客户端校验证书
5. 双方协商密钥
6. 建立加密通道
7. 开始传输 HTTP 数据
总结:
HTTPS 并不是一种新的应用层协议,而是在 HTTP 和 TCP 之间增加了 TLS 加密层。客户端与服务端会先通过 TLS 握手协商加密算法和会话密钥,验证服务端证书合法性,然后使用对称加密传输后续数据。
11. TLS握手和TLS指纹
TLS指纹就是从TLS握手数据中提取出来的一组特征。
关系图
text
TCP三次握手
↓
TLS握手
↓
Client Hello
↓
提取特征
↓
生成TLS指纹(JA3)
↓
风控系统识别客户端
所以:
text
TLS握手 = 行为过程
TLS指纹 = 行为特征
类似于:
text
人走路
↓
摄像头记录
↓
步态特征
text
走路 = TLS握手
步态 = TLS指纹
TLS指纹从哪里来?
服务器最关注的是 TLS 握手中的:
text
Client Hello
因为这是客户端发送的第一份 TLS 数据。
例如 Chrome 发出的 Client Hello:
text
TLS Version:
771
Cipher Suites:
4865
4866
4867
49195
49199
Extensions:
0
11
10
35
16
23
43
45
51
服务器收到后:
text
记录:
TLS版本
加密套件列表
扩展列表
曲线列表
曲线格式
然后拼接:
text
771,
4865-4866-4867-49195-49199,
0-11-10-35-16-23-43-45-51,
29-23-24,
0
最后计算:
text
MD5
得到:
text
e7d705a3286e19ea42f587b344ee6865
这就是:
text
JA3 TLS指纹
为什么浏览器和 requests 指纹不同?
Chrome:
python
# 浏览器
https://www.baidu.com
发送:
text
TLS1.3
Cipher Suites:
4865
4866
4867
Extensions:
0
11
10
35
16
43
45
51
生成:
text
JA3 = Chrome指纹
requests:
python
requests.get(url)
底层:
text
OpenSSL
发送:
text
TLS1.2
Cipher Suites:
49195
49199
49200
Extensions:
0
11
10
35
生成:
text
JA3 = Python指纹
所以:
text
User-Agent一样
TLS指纹不一样
服务器依然知道:
text
你不是Chrome
为什么会403?
很多风控逻辑:
python
if ua == "Chrome":
if ja3 != chrome_ja3:
block()
例如:
请求头:
http
User-Agent:
Chrome 137
看起来像浏览器。
但是 TLS 指纹:
text
Python OpenSSL
服务器判断:
text
伪造浏览器
直接:
http
403 Forbidden
TLS握手中的哪些字段参与指纹?
参考文章: 爬虫TLS指纹校验原理与绕过(Just a moment...)
-
TLS Version
textTLS1.2 TLS1.3 -
Cipher Suites
加密套件:
text4865 4866 4867顺序也重要。
例如:
text4865-4866-4867和
text4867-4865-4866指纹完全不同。
-
Extensions
TLS扩展:
textSNI ALPN Supported Versions Key Share例如:
text0 11 10 35 16 43 45 51 -
Elliptic Curves
椭圆曲线:
textX25519 P256 P384 -
Point Formats
text0
总结:
TLS指纹本质上来源于TLS握手过程中的Client Hello消息。客户端在TLS握手时会发送支持的TLS版本、加密套件、扩展、椭圆曲线等信息,服务器可以根据这些字段生成唯一的TLS指纹(如JA3)。因此TLS握手是建立安全连接的过程,而TLS指纹则是从握手数据中提取出来的客户端特征。很多反爬系统会同时校验User-Agent和TLS指纹,如果UA显示是Chrome,而TLS指纹表现为Python OpenSSL,就可能被判定为自动化程序并返回403。
感谢关注【遇事不決洛必達】!欢迎点赞收藏和交流指正,我会持续分享我的学习经验和心得。