2
requests 库基础
requests: The Swiss Army Knife
requests 是 Python 最流行的 HTTP 库,发请求就一句话。别用标准库的 urllib——requests 是它的优雅升级版。
安装与第一个请求
pip install requests
import requests
resp = requests.get("https://www.example.com")
print(resp.status_code) # 200
print(resp.encoding) # utf-8
print(resp.text[:200]) # HTML 文本
print(resp.content) # 字节(下图片用这个)
response 对象全解
| 属性 | 拿什么 |
|---|---|
resp.status_code | HTTP 状态码(200/404/500) |
resp.text | Unicode 解码后的 HTML 文本 |
resp.content | 原始字节(下图片/文件用) |
resp.json() | JSON 响应转 Python dict |
resp.encoding | 当前编码(可手动改) |
resp.headers | 响应头字典 |
resp.cookies | 服务器种的 Cookie |
resp.url | 最终 URL(可能跟重定向后不一样) |
resp.history | 重定向历史列表 |
resp.raise_for_status() | 4xx/5xx 自动抛异常 |
代理:换 IP 防封
# 免费代理池(别依赖,不稳定)或买付费代理
proxies = {
"http": "http://10.10.1.10:3128",
"https": "http://10.10.1.10:3128",
}
resp = requests.get(url, proxies=proxies, timeout=10)
# SOCKS 代理:pip install requests[socks]
proxies = {"http": "socks5://127.0.0.1:1080"}
Cookie 持久化:下次不用重新登录
# 保存 Cookie 到文件,下次直接用
import http.cookiejar
cookie_file = "cookies.txt"
jar = http.cookiejar.MozillaCookieJar(cookie_file)
# 第一次:登录后保存
session = requests.Session()
session.post(login_url, data={"user":"tom","pass":"123"})
jar.save("cookies.txt")
# 下次:直接加载,不用重新登录
jar.load("cookies.txt")
session.cookies = jar
POST 请求:data 与 json
# 表单提交:data= 字典
requests.post(url, data={"user": "tom", "pass": "123"})
# JSON API:json= 字典(自动序列化)
requests.post(url, json={"query": "python"})
# 文件上传:files=
files = {"file": open("a.jpg", "rb")}
requests.post(url, files=files)
GET 参数与 POST
# GET:params 字典自动拼到 URL 后面
resp = requests.get("https://httpbin.org/get",
params={"q": "Python", "page": 2})
# 实际请求的是 https://httpbin.org/get?q=Python&page=2
# POST:data 表单向服务器提交 / json 发 JSON
resp = requests.post("https://httpbin.org/post",
data={"user": "tom", "pass": "123"})
resp = requests.post("https://httpbin.org/post",
json={"user": "tom"}) # JSON 请求体
请求头:伪装成浏览器
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"Referer": "https://www.google.com/",
}
resp = requests.get("https://httpbin.org/headers", headers=headers)
# 不带 UA?很多网站直接 403
Session:保持登录状态
# requests.Session() 自动管理 Cookie,登录后后续请求自动带
s = requests.Session()
s.headers.update({"User-Agent": "Mozilla/5.0"})
# 第一步:登录
s.post("https://example.com/login", data={"user": "tom", "pass": "123"})
# Cookie 自动存进 session 了
# 第二步:访问登录后页面,自动带 Cookie
resp = s.get("https://example.com/dashboard")
超时与重试
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
s = requests.Session()
retry_strategy = Retry(
total=3, # 最多重试 3 次
backoff_factor=1, # 每次等 1,2,4 秒
status_forcelist=[500, 502, 503],
)
s.mount("https://", HTTPAdapter(max_retries=retry_strategy))
resp = s.get("https://httpbin.org/get", timeout=10) # 超时10秒
代理
proxies = {
"http": "http://127.0.0.1:7890",
"https": "http://127.0.0.1:7890",
}
resp = requests.get("https://httpbin.org/ip", proxies=proxies)
# 被封 IP 时换代理,这是后话(反爬章节细讲)
完整案例:爬豆瓣电影 Top250
# douban_top250.py —— 依赖 pip install requests beautifulsoup4
import requests
from bs4 import BeautifulSoup
import csv
import time
headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"}
with open("douban_top250.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.writer(f)
writer.writerow(["排名", "片名", "评分", "评语"])
for start in range(0, 250, 25): # 10 页,每页 25 部
url = f"https://movie.douban.com/top250?start={start}"
resp = requests.get(url, headers=headers, timeout=10)
soup = BeautifulSoup(resp.text, "html.parser")
for item in soup.select(".item"):
rank = item.select_one(".pic em").text
title = item.select_one(".title").text
score = item.select_one(".rating_num").text
quote = item.select_one(".quote")
quote = quote.text if quote else ""
writer.writerow([rank, title, score, quote])
time.sleep(1) # 礼貌点,别打挂豆瓣
print("爬完了,看 douban_top250.csv")
运行输出
python douban_top250.py
# 爬完了,看 douban_top250.csv
# CSV 里有 250 行:1 肖申克的救赎 9.7 希望让人自由 ...
本章面试题 · requests
1.(概念题)requests.get() 的 timeout 参数为什么必须设?
查看答案
答案:不设 timeout,对方服务器不响应,你的程序会永远挂在那里等。生产爬虫必须设(一般 10-30 秒),超时重试或跳过。
2.(概念题)requests.Session() 比每次 requests.get() 好在哪?
查看答案
答案:Session 复用 TCP 连接(Keep-Alive),省握手开销;自动管理 Cookie,登录后后续请求自动带。爬同一站点时强烈建议用 Session。
3.(代码题)怎么下载一张图片到本地?
查看答案
答案:r = requests.get(url); with open("img.jpg","wb") as f: f.write(r.content)。用 r.content(字节)不是 r.text。