3. HTTP协议与网络请求:数据采集的“交通规则”

做数据采集,说白了就是跟HTTP协议打交道。你写的爬虫、调用的API,底层都在走HTTP。我刚开始接触这行时,觉得协议这东西太理论,结果第一次写爬虫就被反爬搞懵了——后来才发现,很多问题都是因为没吃透HTTP。

这一章,咱们就把HTTP/HTTPS协议、请求方法、头信息、状态码、Cookie和Session这些核心概念,一个一个掰开揉碎。嗯,都是实战中天天用的东西。

核心观点:HTTP协议是数据采集的“语言”。不懂协议,你连服务器在说什么都听不懂,更别说采集数据了。

HTTP 请求-响应基本流程 客户端 (浏览器 / 爬虫) 服务器 (Web / API) ① 请求(Request) GET /api/data HTTP/1.1 ② 响应(Response) HTTP/1.1 200 OK 关键点 • 请求包含:请求行 + 请求头 + 请求体(GET无体) • 响应包含:状态行 + 响应头 + 响应体

3.1 HTTP/HTTPS协议基础

HTTP,全称超文本传输协议。它定义了客户端和服务器之间怎么说话。你想想看,你在浏览器里输入一个网址,背后就是浏览器作为客户端,向服务器发了一条HTTP请求。

HTTPS呢?就是HTTP的加密版本。我在项目中遇到过好几次,采集明文HTTP接口时,数据包被中间人篡改,拿到的数据全是乱码。后来全部切到HTTPS,问题就解决了。

特性 HTTP HTTPS
端口 80 443
加密 明文传输 TLS/SSL加密
安全性 低,易被窃听 高,防篡改防窃听
证书 不需要 需要CA证书
性能 较快 略慢(握手开销)

我的建议:现在做数据采集,能走HTTPS尽量走HTTPS。虽然握手慢一点,但数据完整性有保障。我曾经因为偷懒用HTTP,结果采集到的数据被运营商插入了广告代码,排查了一整天。

3.2 请求方法:GET与POST

HTTP定义了多种请求方法。但做数据采集,你最常用的就两个:GET和POST。

GET请求

GET是用来获取资源的。参数拼在URL后面,用问号分隔。说白了,就是“你给我这个数据”。

# GET请求示例
GET /api/users?id=123&page=1 HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0

我在项目中遇到过一个问题:采集一个分页列表,用GET传page参数,结果URL太长被服务器截断了。后来发现是参数里带了大量筛选条件。嗯,这时候就要考虑用POST了。

POST请求

POST通常用来提交数据。参数放在请求体里,不会暴露在URL中。适合传大量数据或敏感信息。

# POST请求示例
POST /api/login HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 45

{"username": "admin", "password": "123456"}
对比项 GET POST
数据位置 URL参数 请求体
数据长度 有限制(浏览器/服务器限制) 理论上无限制
安全性 低,参数可见 较高,参数在体中
幂等性 是(多次请求结果相同) 否(可能改变服务器状态)
缓存 可被缓存 一般不缓存

避坑指南:我曾经写过一个爬虫,用GET请求提交登录表单,结果密码直接暴露在服务器日志里。后来被安全团队通报了。记住:涉及敏感信息,永远用POST。

3.3 请求头与响应头

HTTP头信息,是客户端和服务器互相传递的“元数据”。你想想看,就像寄快递时填的快递单——收件人、寄件人、包裹类型、重量,都在单子上。

常见请求头

  • Host:目标服务器域名。必须的,没有它服务器不知道你要访问哪个站点。
  • User-Agent:客户端身份标识。我建议你采集时一定要伪装这个,很多反爬就靠它。
  • Referer:来源页面。有些API会校验这个,防止跨站请求。
  • Cookie:携带的会话信息。后面会细讲。
  • Content-Type:请求体的数据格式。比如application/json、application/x-www-form-urlencoded。
  • Authorization:认证信息。Bearer token或Basic auth常用。

常见响应头

  • Content-Type:响应体的数据类型。text/html、application/json等。
  • Set-Cookie:服务器要求客户端设置的Cookie。
  • Cache-Control:缓存策略。no-cache表示不缓存。
  • Location:重定向目标URL。配合301/302状态码使用。
  • Access-Control-Allow-Origin:CORS跨域设置。采集时经常遇到。
# 一个完整的请求-响应示例
# 请求
GET /api/data HTTP/1.1
Host: api.example.com
User-Agent: MyCrawler/1.0
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

# 响应
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: no-cache
Set-Cookie: session_id=abc123; Path=/

{"status": "success", "data": [...]}

我的经验:采集时如果遇到403或406错误,八成是请求头没配好。我习惯先抓包看浏览器正常请求的头信息,然后照搬。特别是User-Agent和Referer,这两个最容易出问题。

3.4 状态码详解

状态码是服务器给你的“回执”。看到不同的状态码,你就知道接下来该怎么做。

状态码 含义 采集时的处理
200 请求成功 正常解析响应体
301/302 重定向 跟进Location头,重新请求
400 请求参数错误 检查参数格式和必填项
401 未认证 检查Token或认证信息
403 禁止访问 被反爬了,换IP或加头
404 资源不存在 检查URL路径是否正确
429 请求过多 限流了,加延时重试
500 服务器内部错误 等一会儿重试,或联系管理员
502/503 服务不可用 服务器挂了,稍后再试

避坑指南:我曾经遇到一个接口,偶尔返回200但响应体是空的。一开始以为是bug,后来发现是服务器在限流时返回了200空体。所以,别只看状态码,还要检查响应体内容。

3.5 Cookie与Session

HTTP是无状态的。服务器记不住你。那怎么实现“登录后保持状态”呢?靠Cookie和Session。

Cookie

Cookie是存储在客户端的小数据块。服务器通过Set-Cookie响应头告诉浏览器存什么,浏览器下次请求时自动带上。

# 服务器设置Cookie
Set-Cookie: session_id=abc123; Domain=.example.com; Path=/; HttpOnly; Secure

# 客户端后续请求自动携带
Cookie: session_id=abc123

Cookie的属性很重要:

  • Domain/Path:限定Cookie的作用范围。
  • Expires/Max-Age:过期时间。不设置就是会话Cookie,关浏览器就没了。
  • HttpOnly:禁止JavaScript读取。防XSS攻击。
  • Secure:仅HTTPS下传输。
  • SameSite:防CSRF攻击。Lax、Strict、None三种模式。

Session

Session是存储在服务器端的数据。服务器生成一个唯一的Session ID,通过Cookie发给客户端。客户端下次请求时带上这个ID,服务器就能找到对应的Session数据。

说白了,Cookie是“通行证”,Session是“档案室”。通行证上只写了个编号,真正的数据存在档案室里。

采集要点:模拟登录时,核心就是拿到Cookie中的Session ID。我建议你用requests.Session()来自动管理Cookie,省得手动处理。但要注意,有些站点会校验User-Agent和IP的一致性,换了IP可能Session就失效了。

# Python示例:使用Session自动管理Cookie
import requests

session = requests.Session()
# 第一次请求:登录
login_data = {"username": "admin", "password": "123456"}
resp = session.post("https://example.com/login", data=login_data)
# 此时session对象已经自动保存了服务器返回的Cookie

# 后续请求:自动携带Cookie
data = session.get("https://example.com/api/data").json()
print(data)

Cookie与Session的对比

对比项 Cookie Session
存储位置 客户端(浏览器) 服务器端
存储容量 有限(一般4KB) 理论上无限制
安全性 较低,可被篡改 较高,数据在服务端
生命周期 由Expires控制 由服务器配置控制
依赖关系 独立存在 通常依赖Cookie传递Session ID

我的习惯:采集需要登录的站点时,我会先用浏览器手动登录,然后从开发者工具里把Cookie复制出来,写到代码里。这样能避免登录逻辑的复杂性。但要注意Cookie会过期,需要定期刷新。

嗯,HTTP协议这块内容不少,但都是数据采集的基石。你把这些搞懂了,后面写爬虫、调API就会顺手很多。记住:协议是死的,但应用是活的。多抓包、多分析,慢慢就有感觉了。