06 Python HTTP 请求入门

📅 2026/7/30 17:41:33 👁️ 阅读次数 📝 编程学习
06 Python HTTP 请求入门

Python HTTP 请求入门

一、程序怎么和外界通信

你的 Python 脚本 ──HTTP 请求──▶ 远程服务器(API) ◀──HTTP 响应── 返回 JSON / 文本

二、requests 入门

安装 requests

requests 是 Python 最常用的 HTTP 库,语法简单

项目根目录下,先激活虚拟环境,再安装:

cd D:\test\python_study python -m venv .venv .venv\Scripts\activate pip install requests

验证:

python-c"import requests; print(requests.__version__)"
第 1 行:python -m venv .venv

作用:创建虚拟环境

部分含义
python调用系统里的 Python
-m venv以模块方式运行 venv(Python 自带的虚拟环境工具)
.venv在当前目录下创建名为 .venv 的文件夹

执行后会在项目根目录生成 .venv/,里面有独立的 Python 和 pip,依赖只装在这个项目里,不影响系统全局 Python。
类比前端: 类似在项目里初始化一个独立的依赖空间(类似有独立 node_modules 的项目环境),而不是用全局安装的包。

第 2 行:.venv\Scripts\activate

作用:激活虚拟环境

执行后,当前终端会「切换」到 .venv 里的 Python 和 pip。成功后提示符前会出现 (.venv)`,例如:

(.venv) PS D:\test\python_study>
第 3 行:pip install requests

作用:在当前环境里安装 requests 这个第三方包

部分含义
pipPython 的包管理器(类似前端的 npm / pnpm)
install安装依赖(类似 npm install)
requests要安装的包名,用来发 HTTP 请求

前提是你已经激活了虚拟环境(提示符里有 (.venv)),这样包装进项目的 .venv,不会污染全局 Python。

GET 请求的两种传参

类型写法例子
路径参数写在 URL 路径里/posts/1/api/voi/123
查询参数写在?后面(Query String)/posts?userId=1

前端路由里的params(如/api/voi/:id)指的是路径参数;Pythonrequests里的params=指的是查询参数,不要混用。

路径参数:直接拼进 URL

post_id=1response=requests.get(f"https://jsonplaceholder.typicode.com/posts/{post_id}")data=response.json()# 返回 dict,id=1 的那篇文章

查询参数:URL 后面加?key=value

https://jsonplaceholder.typicode.com/posts?userId=1

params=传查询参数,更清晰:

response=requests.get("https://jsonplaceholder.typicode.com/posts",params={"userId":1},)print(response.url)# 看最终拼好的 URLdata=response.json()# 返回 list,该用户的所有帖子

推荐的公开测试 API

本课用 JSONPlaceholder — 免费、稳定、无需 API Key:

端点说明
GET /posts/1获取 id=1 的文章(返回 dict)
GET /posts?userId=1获取 userId=1 的所有文章(返回 list)
GET /users/1获取 id=1 的用户信息

常见错误

错误原因
ModuleNotFoundError: No module named ‘requests’没安装或虚拟环境没激活
ConnectionError网络不通或 URL 写错
KeyErrorJSON 字段名写错,先用 print(data) 看结构
不检查 status_code 直接用 .json()404/500 时可能解析失败

三、POST 请求

发 POST 的几种方式

# 方式 1:发 JSON(推荐,API 最常用)# json= 会自动做两件事:把 dict 转成 JSON 字符串,并设置 Content-Type: application/json。requests.post(url,json={"key":"value"})# 方式 2:手动发 JSON 字符串(需自己设 Content-Type)# 用 data= 传字符串时,requests 默认是 application/x-www-form-urlencoded(表单编码),需手动设为 JSON。requests.post(url,data='{"key": "value"}',headers={"Content-Type":"application/json"})# 方式 3:纯文本requests.post(url,data='hello world',headers={"Content-Type":"text/plain"})# 方式 4:表单字段(data 传 dict 时常见)requests.post(url,data={"key":"value"})# 默认 application/x-www-form-urlencoded

Header(请求头 / 响应头)

Header 是请求的「元信息」,键值对形式。

常见请求头
Header作用例子
Content-TypeBody 是什么格式application/json
Authorization身份认证Bearer sk-xxxx(LLM API 常用)
User-Agent客户端是谁MyApp/1.0
在 requests 里设置 Header
headers={"User-Agent":"PythonStudy/1.0"}response=requests.get(url,headers=headers)
看响应头
print(response.headers)# 全部响应头print(response.headers.get("Content-Type"))# 常见:application/json; charset=utf-8

HTTP 状态码

状态码含义你该怎么想
200OK,成功正常处理 response.json()
201Created,创建成功POST 创建资源时常见
400Bad Request,请求有误检查 Body、参数格式
401Unauthorized,未授权缺 API Key 或 Key 无效
404Not Found,找不到URL 或 id 写错(你测过 99990)
500Internal Server Error服务器内部错误

通过response.status_code读取。

读响应体

response.text# 字符串(原始文本)response.json()# 解析成 dict/list(前提是 JSON)response.content# 二进制 bytes(图片等)

对象属性 和 字典键 的区别

response ← httpx.Response 对象 ├── status_code ← 对象的属性(int) ├── headers ← 对象的属性(Headers 映射) │ └── "Content-Type" ← headers 里的一个键(字符串) └── ...

四、httpx — API(支持 async/await:)

安装 httpx

环境同上,pip install httpx

保存二进制文件

文本用 write_text(),图片用 write_bytes():

frompathlibimportPath path=Path("downloads/cat.jpg")path.parent.mkdir(parents=True,exist_ok=True)# 确保目录存在path.write_bytes(response.content)# 写入二进制
parents=True

自动创建路径上所有缺失的上级目录。
比如:会依次创建:a → a/b → a/b/c。
如果 parents=False(默认),中间缺一层就会报错。

exist_ok=True

目录已经存在时不报错。

exist_ok=False(默认):目录已存在 → 抛 FileExistsError
exist_ok=True:目录已存在 → 静默跳过
常见组合就是「缺啥建啥,有了也不报错」。

httpx 异步下载一张图

importhttpxasyncdefdownload_image(url:str,save_path:Path)->bool:asyncwithhttpx.AsyncClient(timeout=30.0)asclient:response=awaitclient.get(url)ifresponse.status_code==200:save_path.write_bytes(response.content)returnTruereturnFalse

response.content 是 bytes 类型,正好对应图片二进制数据。