单元 1 · 爬虫基础 — 预计 40 分钟
requests 入门
📍 本课路径
- 发起 GET 与 POST 请求
- 携带参数与请求头
- 使用 Session 保持状态
- 正确处理超时与异常
🎯 学习节奏:① 看目标 → ② 先思考再动手 → ③ 在运行器写代码 → ④ 失败时按提示重试 → ⑤ 通过后看思路
上一章把 HTTP 讲清楚了,这一章用 requests 把它变成代码。requests 是 Python 里最流行的 HTTP 库,把「发请求」从十几行收成了两三行。
浏览器运行器里已经预装
requests,但下面凡涉及真实联网的示例都用代码块展示(浏览器内的联网受跨域限制),可运行示例集中在「参数拼装」这类纯逻辑部分。
一、第一个 GET 请求
import requests
resp = requests.get("https://books.example.com/list")
print(resp.status_code) # 200
print(resp.url) # 实际访问的地址(含重定向后的)
print(len(resp.text)) # 网页 HTML 文本长度
resp(Response 对象)是你最该熟悉的东西:
| 属性 | 含义 |
|---|---|
resp.status_code |
状态码(200/403/404…) |
resp.text |
解码后的网页文本(字符串) |
resp.content |
原始字节(下载图片/文件用) |
resp.headers |
响应头字典 |
resp.url |
最终 URL(跟随重定向后) |
resp.encoding |
编码,乱码时手动设 resp.encoding = "utf-8" |
二、查询参数:用 params 代替手拼 URL
别手写 ?q=python&page=2,交给 params 字典,requests 会自动编码:
resp = requests.get(
"https://books.example.com/search",
params={"q": "python", "page": 2},
)
print(resp.url) # https://books.example.com/search?q=python&page=2
下面这段在浏览器里就能跑——你需要补全「把字典拼成查询串」的逻辑,这正是 requests.params 在背后做的事:
# TODO 1: 从 urllib.parse 导入 urlencode, urlparse, parse_qs
from urllib.parse import urlencode, urlparse, parse_qs
base = "https://books.example.com/search"
params = {"q": "python 爬虫", "page": "2"}
# TODO 2: 用 urlencode(params) 将字典编码为查询字符串,拼接到 base 后面
url = base + "?" + urlencode(params)
print("最终 URL:", url)
# TODO 3: 反向验证——用 urlparse + parse_qs 把刚拼的 URL 解回来,打印参数
print("解析回参数:", parse_qs(urlparse(url).query))三、请求头与 UA 伪装
很多站点看到「没有 User-Agent 的请求」就直接 403。requests 默认 UA 是 python-requests/x.x,很容易露馅:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept-Language": "zh-CN,zh;q=0.9",
}
resp = requests.get("https://books.example.com/list", headers=headers)
把浏览器 F12 → Network 里看到的真实
User-Agent抄过来,是最快的方式。
四、POST 请求:提交数据
登录、搜索表单多用 POST,参数放在请求体里:
# 表单格式
resp = requests.post(url, data={"username": "u", "password": "p"})
# JSON 格式(接口常见)
resp = requests.post(url, json={"key": "value"})
五、Session:保持登录态
每次 requests.get 都是「新会话」,不带 Cookie。要维持登录,用 Session,它会自动保存并带上 Cookie:
s = requests.Session()
s.post(login_url, data={"user": "u", "pwd": "p"}) # 拿到登录 Cookie
resp = s.get(protected_url) # 同一会话,自动带 Cookie
六、超时与异常处理
永远给请求加超时,否则网站卡住你的脚本会一直挂起:
try:
resp = requests.get(url, timeout=5) # 5 秒超时
resp.raise_for_status() # 状态码非 2xx 时主动抛异常
except requests.exceptions.Timeout:
print("超时,稍后重试")
except requests.exceptions.RequestException as e:
print("请求失败:", e)
raise_for_status() 是把「静默的 4xx/5xx」变成异常的好习惯,配合 try/except 才能写出健壮爬虫。
七、小结
requests.get(url)/requests.post(url, data=, json=)发请求。- 响应对象
resp:status_code/text/content/headers/url。 - 参数用
params=,别手拼;请求头用headers=伪装 UA。 - 需要登录态用
Session();联网务必加timeout+try/except。 resp.raise_for_status()让错误显式化,是健壮爬虫的第一步。