Appearance
章节 1:爬虫基础与网络协议
学习目标
- 深入理解 HTTP/HTTPS 协议的工作原理与报文结构
- 掌握 Requests 库的 Session 管理、请求伪装等高级用法
- 熟练使用 Fiddler 进行抓包、断点调试与请求修改
- 了解爬虫法律风险、robots.txt 规范与职业伦理
1.1 HTTP/HTTPS 协议深度拆解
1.1.1 HTTP 协议基础
定义:HTTP(HyperText Transfer Protocol,超文本传输协议)是客户端与服务器之间传输超媒体文档的应用层协议,是爬虫与目标服务器通信的基础。
请求报文结构:
http
POST /api/login HTTP/1.1 ← 请求行:方法 + URL + 版本
Host: example.com ← 请求头(Headers)
User-Agent: Mozilla/5.0 ...
Content-Type: application/json
Cookie: session_id=abc123
{"username":"admin","password":"123456"} ← 请求体(Body)响应报文结构:
http
HTTP/1.1 200 OK ← 状态行:版本 + 状态码 + 短语
Content-Type: text/html; charset=utf-8
Set-Cookie: token=xyz789
Content-Length: 1234
<!DOCTYPE html><html>...</html> ← 响应体(Body)HTTP 方法速查表:
| 方法 | 语义 | 是否有体 | 幂等 | 爬虫中用途 |
|---|---|---|---|---|
| GET | 获取资源 | 否 | 是 | 请求页面 / 公开数据 |
| POST | 提交/创建资源 | 是 | 否 | 登录、提交表单、API 查询 |
| PUT | 全量更新资源 | 是 | 是 | 更新数据 |
| DELETE | 删除资源 | 否 | 是 | 删除操作 |
| PATCH | 部分更新资源 | 是 | 否 | 局部更新 |
状态码分类:
| 状态码范围 | 类别 | 常见状态码 |
|---|---|---|
| 1xx | 信息性 | 100 Continue, 101 Switching Protocols |
| 2xx | 成功 | 200 OK, 201 Created, 204 No Content |
| 3xx | 重定向 | 301 Moved Permanently, 302 Found, 304 Not Modified |
| 4xx | 客户端错误 | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found |
| 5xx | 服务端错误 | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable |
1.1.2 HTTPS 与 TLS 握手
定义:HTTPS = HTTP + SSL/TLS,通过加密通信保证数据传输的机密性、完整性和服务器身份验证。
TLS 1.3 握手过程(简化):
Client Server
│ │
├── ClientHello (支持的密码套件) ──────→ │
│ ├── ServerHello (选定套件)
│ ├── Certificate (服务器证书)
│ ├── ServerFinished ──→
│ ←── ClientFinished ────────────────── │
│ ←──────── 加密数据传输 ──────────────→ │关键概念:
- 证书(Certificate):由 CA 签发,包含公钥和域名信息,验证服务器身份
- 对称加密:使用共享密钥加密实际数据(如 AES),速度快
- 非对称加密:使用公钥/私钥对交换对称密钥(如 RSA、ECDHE),仅用于握手阶段
1.1.3 Cookie 与 Session 机制
定义:HTTP 是无状态协议,Cookie/Session 机制为服务器提供"记忆"能力。
工作原理:
第一次请求:POST /login
└→ 服务器验证身份后,创建 Session,返回 Set-Cookie: session_id=abc123
第二次请求:GET /profile Cookie: session_id=abc123
└→ 服务器根据 Cookie 查找 Session,识别用户身份爬虫中处理 Cookie 的三种方式:
python
# 方式一:直接传入字典
cookies = {"session_id": "abc123"}
resp = requests.get("https://example.com/profile", cookies=cookies)
# 方式二:使用 Session 对象自动管理
s = requests.Session()
s.post("https://example.com/login", data={"user": "admin", "pass": "123"})
resp = s.get("https://example.com/profile") # 自动携带 Cookie
# 方式三:从浏览器导出 Cookie 字符串
cookies_str = "session_id=abc123; token=xyz789"
cookies_dict = {kv.split("=")[0].strip(): kv.split("=")[1].strip()
for kv in cookies_str.split(";")}
resp = requests.get("https://example.com/profile", cookies=cookies_dict)1.2 Requests 请求库进阶
1.2.1 Session 对象
定义:requests.Session() 在同一个会话实例中持久化 Cookie、连接池和默认配置,适合需要维护登录状态的爬虫场景。
python
import requests
# 创建 Session
session = requests.Session()
# 设置全局默认 Headers
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept-Language": "zh-CN,zh;q=0.9",
})
# 登录(Cookie 自动保存到 Session)
login_data = {"username": "test_user", "password": "test_pass"}
session.post("https://httpbin.org/post", data=login_data)
# 后续请求自动携带 Cookie
resp = session.get("https://httpbin.org/cookies")
print(resp.json()) # 包含登录后的 Cookie1.2.2 GET 请求参数详解
python
import requests
# 基础 GET
resp = requests.get("https://api.github.com/search/repositories")
# URL 参数——方式一:params 字典
params = {"q": "python爬虫", "sort": "stars", "order": "desc"}
resp = requests.get("https://api.github.com/search/repositories", params=params)
print(resp.url) # https://api.github.com/search/repositories?q=python爬虫&sort=stars&order=desc
# URL 参数——方式二:直接拼接
resp = requests.get("https://httpbin.org/get?page=1&size=20")
# 请求头伪装
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Referer": "https://www.google.com/",
"Origin": "https://example.com",
"X-Requested-With": "XMLHttpRequest", # 标识 AJAX 请求
}
resp = requests.get("https://example.com/api/data", headers=headers)
# 超时设置(必设!)
resp = requests.get("https://example.com", timeout=(5, 10))
# timeout = (connect_timeout, read_timeout)1.2.3 POST 请求与数据提交
python
import requests
# Form Data(application/x-www-form-urlencoded)
data = {"username": "admin", "password": "123456"}
resp = requests.post("https://httpbin.org/post", data=data)
print(resp.json()["form"]) # {'username': 'admin', 'password': '123456'}
# JSON Data(application/json)
json_data = {"name": "test", "age": 18}
resp = requests.post("https://httpbin.org/post", json=json_data)
print(resp.json()["json"]) # {'name': 'test', 'age': 18}
# Multipart(文件上传)
files = {
"file": ("report.pdf", open("report.pdf", "rb"), "application/pdf"),
"description": (None, "月度报告"),
}
resp = requests.post("https://httpbin.org/post", files=files)1.2.4 Headers 伪装技巧
python
import requests
# 完整浏览器伪装
headers = {
# 必须——标识客户端
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36",
# 来源——很多网站校验
"Referer": "https://www.example.com/products",
# 请求来源域名
"Origin": "https://www.example.com",
# AJAX 标识(很多 API 接口要求)
"X-Requested-With": "XMLHttpRequest",
# 接受的内容类型
"Accept": "text/html,application/json,*/*",
# 编码
"Accept-Encoding": "gzip, deflate, br",
# 语言偏好
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
}1.2.5 异常处理与重试机制
python
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# 带重试的 Session
session = requests.Session()
retry_strategy = Retry(
total=3, # 总重试次数
backoff_factor=1, # 重试等待:1s, 2s, 4s
status_forcelist=[500, 502, 503, 504], # 这些状态码触发重试
allowed_methods=["GET", "POST"],
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
session.mount("http://", adapter)
try:
resp = session.get("https://httpbin.org/status/500", timeout=5)
except requests.exceptions.ConnectionError:
print("连接失败")
except requests.exceptions.Timeout:
print("请求超时")
except requests.exceptions.RequestException as e:
print(f"请求异常: {e}")1.3 Fiddler 抓包工具
1.3.1 Fiddler 原理与安装
定义:Fiddler 是一款 HTTP/HTTPS 调试代理工具,通过设置本地代理(127.0.0.1:8888)拦截并记录所有经过的 HTTP/HTTPS 流量。
工作原理:
浏览器/App ──→ Fiddler (代理 8888) ──→ 目标服务器
│
流量记录、修改、重放HTTPS 解密配置:
- 菜单栏 → Tools → Options → HTTPS
- 勾选 "Capture HTTPS CONNECTs" 和 "Decrypt HTTPS traffic"
- 在弹出的安装证书窗口中确认(首次需要安装 Fiddler Root CA)
1.3.2 界面布局与核心功能
┌────────────────────────────────────────────────────────────────┐
│ 工具栏:注释 | 重放 | 清除 | 断点 | 解码 | 过滤 │
├───────────────────────┬────────────────────────────────────────┤
│ │ │
│ 会话列表 (左侧) │ 详情面板 (右侧) │
│ │ │
│ # Result Proto URL │ 📄 Inspectors │
│ 200 200 HTTP /a │ ├─ Request: Headers / TextView / ... │
│ 201 301 HTTP /b │ └─ Response: Headers / TextView /... │
│ 202 404 HTTP /c │ │
│ │ 🎯 AutoResponder / Composer / Fiddler │
├───────────────────────┴────────────────────────────────────────┤
│ 命令行 (底部):输入 help 查看命令 │
└────────────────────────────────────────────────────────────────┘常用命令行:
| 命令 | 说明 |
|---|---|
?keyword | 筛选 URL 包含关键字 |
>200 | 筛选状态码大于 200 |
=200 | 筛选状态码等于 200 |
@host.com | 筛选指定域名的请求 |
select image | 选中所有图片类型 |
1.3.3 断点调试与请求修改
全局断点(拦截所有请求):
- 菜单栏 → Rules → Automatic Breakpoints → Before Requests
- 或按快捷键
F11切换
请求修改步骤:
- Fiddler 拦截请求后,转到 Inspectors → Request
- 修改 Headers、Body 或 URL
- 点击 "Run to Completion"(或按
G键)放行
示例:修改 User-Agent
拦截请求后,在 Headers 中找到 User-Agent 行
修改为:User-Agent: CustomBot/1.0
点击 "Run to Completion"1.3.4 移动端抓包
Android 设备抓包步骤:
- Fiddler 端:Tools → Options → Connections,勾选 "Allow remote computers to connect"(默认端口 8888)
- 查看 Fiddler 所在电脑的 IP:命令行执行
ipconfig - Android 设备设置:
- 设置 → WLAN → 长按连接的网络 → 修改网络
- 代理选择"手动",填入电脑 IP 和端口 8888
- 浏览器访问
http://电脑IP:8888,下载并安装 Fiddler 根证书 - 此时所有手机流量均可在 Fiddler 中查看
iOS 设备抓包注意事项:
- 需要安装 Fiddler 证书并在 "设置 → 通用 → 关于本机 → 证书信任设置" 中开启信任
- iOS 10.3+ 需要额外添加信任
1.3.5 AutoResponder(自动响应)
用途:将远程资源替换为本地文件,用于调试或绕过前端校验。
python
# 配置步骤:
# 1. 拖拽会话到 AutoResponder 面板
# 2. 勾选 "Enable rules" 和 "Unmatched requests passthrough"
# 3. 选择响应方式:
# - Find a file...(返回本地文件)
# - Create New Response(返回自定义响应)
# - 200-blocking(直接返回空 200)1.4 爬虫法律风险与 robots.txt
1.4.1 爬虫法律风险
定义:网络爬虫在采集数据时可能触犯的法律法规,主要包括《网络安全法》《数据安全法》《个人信息保护法》和《反不正当竞争法》。
高风险行为(红线):
| 行为类型 | 法律风险 | 典型案例 |
|---|---|---|
| 绕过登录验证 | 非法获取计算机信息系统数据罪 | 爬取需要登录才能访问的数据 |
| 绕过反爬措施 | 破坏计算机信息系统罪 | 恶意绕过 CAPTCHA、IP 封锁 |
| 采集个人信息 | 侵犯公民个人信息罪 | 爬取手机号、身份证、地址等 |
| 抓取商业竞品数据 | 不正当竞争 | 大规模爬取电商商品价格进行比价 |
| 造成服务器过载 | 民事侵权 / 刑事破坏 | 无限制并发导致目标服务器崩溃 |
安全实践守则:
✅ 遵守 robots.txt 协议
✅ 设置合理请求间隔(避免对服务器造成压力)
✅ 只采集公开数据(无需登录即可访问)
✅ 尊重数据的版权和使用条款
✅ 对采集的个人信息进行脱敏处理
✅ 存储数据时添加时间戳和来源标记
❌ 不要爬取需要付费访问的内容
❌ 不要爬取登录后才能查看的用户隐私信息
❌ 不要使用分布式爬虫攻击单一服务器
❌ 不要将爬取数据用于商业竞争1.4.2 robots.txt 协议
定义:robots.txt 是存放在网站根目录的文本文件,告知爬虫哪些路径允许或禁止抓取。
语法规则:
# robots.txt 示例
User-agent: * # 适用于所有爬虫
Disallow: /admin/ # 禁止爬取 /admin/ 路径
Disallow: /private/ # 禁止爬取 /private/ 路径
Allow: /public/ # 允许爬取 /public/ 路径
Crawl-delay: 10 # 请求间隔 10 秒
User-agent: Googlebot # 仅适用于 Google 爬虫
Disallow: /temp/Python 中解析 robots.txt:
python
from urllib.robotparser import RobotFileParser
rp = RobotFileParser()
rp.set_url("https://www.example.com/robots.txt")
rp.read()
# 检查是否允许爬取
url = "https://www.example.com/private/data.html"
user_agent = "MySpider/1.0"
if rp.can_fetch(user_agent, url):
print("允许爬取")
else:
print("禁止爬取")小结
- HTTP 协议是爬虫的基础,理解请求/响应报文结构、方法语义和状态码分类是调试的第一步
- HTTPS 通过 TLS 加密保证通信安全,爬虫需要处理证书验证
- Requests 的 Session 对象自动管理 Cookie,是模拟登录状态的核心工具
- Headers 伪装是绕过反爬的基础手段,User-Agent 和 Referer 最为关键
- Fiddler 是抓包调试利器,支持断点修改请求、HTTPS 解密和移动端抓包
- 爬虫从业者必须知法守法,尊重 robots.txt,合理控制请求频率
练习
- Requests 基础:使用
requests库请求https://httpbin.org/get,添加自定义 Headers(User-Agent、Referer),打印返回的状态码和响应头。 - Session 登录模拟:使用
requests.Session()模拟登录流程:先 POST 到https://httpbin.org/post提交表单,再 GEThttps://httpbin.org/cookies验证 Cookie 是否被自动携带。 - Fiddler 抓包实战:启动 Fiddler,用浏览器访问任意网站,在 Fiddler 中找到:
- 所有图片资源的请求(提示:
select image) - 状态码为 404 的请求
- 修改其中一个请求的 User-Agent 后放行
- 所有图片资源的请求(提示:
- robots.txt 分析:访问
https://www.baidu.com/robots.txt,分析其规则,用urllib.robotparser检查https://www.baidu.com/s?wd=test是否允许爬取。 - 异常处理:编写一个带重试机制的请求函数,测试对
https://httpbin.org/status/500的请求,验证重试 3 次后抛出异常。