跳到主要内容

HTTP 基础

理解 HTTP 协议是写好爬虫的基础。本章将介绍 HTTP 的核心概念,帮助你更好地理解网络请求和响应。

什么是 HTTP?

HTTP(HyperText Transfer Protocol,超文本传输协议)是客户端和服务器之间的通信协议。当你在浏览器中访问一个网页时,浏览器会向服务器发送 HTTP 请求,服务器则返回 HTTP 响应。

URL 详解

URL(Uniform Resource Locator,统一资源定位符)是网页的地址。一个完整的 URL 包含多个部分:

https://www.example.com:443/path/to/page?id=123#section
│ │ │ │ │ │
│ │ │ │ │ └─ 锚点(不发送给服务器)
│ │ │ │ └─────────── 查询参数
│ │ │ └────────────────────────── 路径
│ │ └────────────────────────────── 端口
│ └──────────────────────────────────────────── 域名
└──────────────────────────────────────────────────── 协议

URL 各部分说明:

部分说明示例
协议通信协议http, https, ftp
域名服务器地址www.example.com
端口服务端口(可选):443, :8080
路径资源位置/path/to/page
查询参数传递给服务器的参数?id=123&page=1
锚点页面内定位#section

HTTP 请求

请求方法

HTTP 定义了多种请求方法,最常用的是 GET 和 POST:

方法说明用途
GET获取资源浏览网页、获取数据
POST提交数据登录、提交表单
PUT更新资源更新数据
DELETE删除资源删除数据
HEAD获取响应头检查资源是否存在

GET 请求

GET 请求将参数放在 URL 中,用于请求数据:

GET /search?q=python&page=1 HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html

特点:

  • 参数暴露在 URL 中
  • 适合查询操作
  • 有长度限制(浏览器通常限制 2000 字符左右)

POST 请求

POST 请求将数据放在请求体中,用于提交数据:

POST /login HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0

username=admin&password=123456

特点:

  • 数据放在请求体中,更安全
  • 无大小限制
  • 适合提交表单、上传文件

请求头

请求头包含关于请求的元数据:

# 常见的请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Referer': 'https://www.example.com/', # 来源页面
'Cookie': 'session_id=abc123', # Cookie 信息
}

常用请求头说明:

请求头说明
User-Agent标识客户端类型(浏览器/爬虫)
Accept告诉服务器客户端能接受的响应类型
Accept-Language接受的语言
Accept-Encoding可接受的编码方式(如 gzip)
Referer请求的来源页面
Cookie携带的 Cookie 信息

HTTP 响应

状态码

HTTP 响应包含一个状态码,表示请求的结果:

常见状态码:

状态码含义说明
200OK请求成功
201Created资源创建成功
301Moved Permanently永久重定向
302Found临时重定向
304Not Modified资源未修改,使用缓存
400Bad Request请求语法错误
401Unauthorized需要认证
403Forbidden拒绝访问
404Not Found资源不存在
429Too Many Requests请求过于频繁
500Internal Server Error服务器内部错误
502Bad Gateway网关错误
503Service Unavailable服务不可用
504Gateway Timeout网关超时

响应头

响应头包含关于响应的元数据:

# 常见的响应头
response.headers = {
'Content-Type': 'text/html; charset=utf-8', # 内容类型
'Content-Length': '12345', # 内容长度
'Server': 'nginx/1.18.0', # 服务器类型
'Date': 'Sat, 25 Mar 2024 00:00:00 GMT', # 响应时间
'Set-Cookie': 'session=abc123; HttpOnly', # 设置 Cookie
'Cache-Control': 'no-cache', # 缓存控制
'Expires': 'Sat, 25 Mar 2024 00:00:00 GMT', # 过期时间
}

响应体

响应体是服务器返回的实际内容,常见格式:

  1. HTML - 网页内容
  2. JSON - API 接口常用
  3. XML - 某些老旧 API 使用
  4. 图片/视频/文件 - 二进制数据
  5. 纯文本 - 简单文本内容

Cookie 是服务器保存在客户端的数据,用于维持会话状态:

import requests

# 方式1:手动设置 Cookie
cookies = {
'session_id': 'abc123',
'user_token': 'xyz789'
}
response = requests.get('https://example.com/profile', cookies=cookies)

# 方式2:使用 Session 自动管理 Cookie
session = requests.Session()

# 登录(服务器会设置 Cookie)
session.post('https://example.com/login', data={
'username': 'user',
'password': 'pass'
})

# 后续请求会自动携带 Cookie
response = session.get('https://example.com/profile')
print(response.text)

Session 和 Token

Session 认证

传统的会话认证方式:

# Session 认证流程
session = requests.Session()

# 1. 登录
login_data = {
'username': 'your_username',
'password': 'your_password'
}
session.post('https://example.com/login', data=login_data)

# 2. 访问需要登录的页面
response = session.get('https://example.com/member/info')

Token 认证

现代 API 常用的认证方式:

import requests

# 1. 获取 Token
auth_data = {
'username': 'your_username',
'password': 'your_password'
}
response = requests.post('https://example.com/api/login', json=auth_data)
token = response.json()['token']

# 2. 使用 Token 请求
headers = {
'Authorization': f'Bearer {token}'
}
response = requests.get('https://example.com/api/user', headers=headers)

HTTP 代理

使用代理可以隐藏真实 IP,避免被封禁:

import requests

# 使用代理
proxies = {
'http': 'http://127.0.0.1:7890',
'https': 'http://127.0.0.1:7890'
}

response = requests.get('https://example.com', proxies=proxies)

# 认证代理
proxies_with_auth = {
'http': 'http://user:[email protected]:7890',
}

HTTPS 和 SSL

HTTPS 是 HTTP 的安全版本,使用 SSL/TLS 加密:

import requests

# 忽略 SSL 证书验证(不推荐,仅用于测试)
response = requests.get('https://example.com', verify=False)

# 指定 SSL 证书
response = requests.get('https://example.com', cert='/path/to/cert.pem')

小结

本章我们学习了:

  1. URL 构成 - 协议、域名、端口、路径、查询参数
  2. HTTP 请求方法 - GET、POST 等
  3. 请求头和响应头 - HTTP 元数据
  4. 状态码 - 表示请求结果
  5. Cookie 和 Session - 会话管理
  6. 代理 - 隐藏真实 IP

理解这些 HTTP 基础知识对于编写高效的爬虫至关重要。

练习

  1. 使用浏览器开发者工具查看一个网页的请求和响应头
  2. 分析 URL 中的查询参数如何构造
  3. 理解 301、302、404、429 等常见状态码的含义