楼层: 首页/ 软件技术/ Python 爬虫技术/ requests 库基础
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_codeHTTP 状态码(200/404/500)
resp.textUnicode 解码后的 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。