基于FastAPI的API开发(爬虫的工作原理):从设计到部署详解+面试习题

API(Application Programming Interface)是不同软件系统之间的通信接口,是现代软件架构的核心组件。本文将从 基础概念到实际实现 ,详细讲解API开发的全流程。

一、API基础概念

1. 什么是API?

API是一组定义的规则和协议,允许一个软件系统与另一个软件系统交互,而无需了解其内部实现细节。

例如:

  • 天气应用通过天气API获取实时天气数据

  • 移动应用通过后端API与服务器通信

2. API的类型

  • REST API :基于HTTP协议,使用标准HTTP方法,是目前最流行的API类型

  • GraphQL API :允许客户端精确请求所需数据,减少网络传输

  • SOAP API :基于XML的重量级API,主要用于企业级应用

  • WebSocket API :提供双向实时通信,适合聊天、实时更新等场景

作者有话说:API开发一般都是WebAPI开发。

3. API核心原则

REST(Representational State Transfer)是一种API设计风格,遵循以下原则:

  • 资源为中心 :使用URL表示资源(如 /users 、 /products/123 )
  • HTTP方法表示操作 :

  • GET :获取资源

  • POST :创建资源

  • PUT :更新资源

  • PATCH :部分更新资源

  • DELETE :删除资源

  • 无状态 :每个请求都包含完整的状态信息,服务器不保存客户端状态

  • 统一接口 :使用标准HTTP状态码和头信息

  • 资源表示 :使用JSON或XML表示资源

二、HTTP请求格式

GET请求: 查询请求(get请求)一般请求体为空

四、HTTP响应格式

post请求:提交修改请求(隐秘数据修改post请求)一般加密;请求体一般不显示在URL中

\r\n\r\n:换行请求体和请求行中间一个空行

响应协议格式

回来流程:

五、API设计:规范与最佳实践

1. 设计流程

  1. 需求分析 :明确API的功能和使用场景

  2. 资源建模 :识别系统中的核心资源(如用户、产品、订单)

  3. 路径设计 :为每个资源定义清晰的URL路径

  4. 参数设计 :定义查询参数、路径参数和请求体

  5. 响应设计 :定义响应格式和状态码

  6. 认证授权 :设计安全机制

2. URL路径设计

  • 使用复数名词 : /users 而非 /user

  • 嵌套资源 :表示资源之间的关系,如 /users/123/orders

  • 避免动词 :使用HTTP方法表示操作,而非URL中包含动词(如 /users/123 而非 /getUser/123 )

  • 保持简洁 :避免过长或复杂的路径
    URL:本质上是向服务器增删改查数据,多数是查

协议://域名/路径?查寻参数

3. 请求与响应设计 请求设计

  • 路径参数 :用于标识特定资源(如 /users/{id} )

  • 查询参数 :用于过滤、排序和分页(如 /users?page=1&limit=10 )

  • 请求体 :用于创建或更新资源,通常使用JSON格式

  • 头信息 :用于传递元数据(如认证令牌、内容类型) 响应设计

  • 使用标准HTTP状态码 :
  • 200 OK:请求成功

  • 201 Created:资源创建成功

  • 204 No Content:请求成功但无响应体

  • 400 Bad Request:请求格式错误

  • 401 Unauthorized:未授权

  • 403 Forbidden:禁止访问

  • 404 Not Found:资源未找到

  • 500 Internal Server Error:服务器内部错误

  • 统一响应格式(字典内套字典) :

{

"status": "success",

"data": {...}, // 响应数据

"message": "请求成功"

}

错误响应 (字典内套字典又套列表):

{

"status": "error",

"error": {

"code": "INVALID_PARAMETER",

"message": "参数验证失败",

"details": [

{"field": "email", "message": "必须是有效的邮箱地址"}

]

}

}

返回两种格式:josn和HTML

josn:提供接口

HTML:提供给用户

4. 数据验证

  • 请求参数验证 :确保传入的数据符合预期格式和约束

  • 数据类型验证 :检查字符串、数字、日期等类型

  • 业务规则验证 :检查数据是否满足业务逻辑要求(如邮箱唯一性)

六、API开发实现

1.什么是框架?

就相当于一个模版,我在这个模版上做一些修改。

2.下载框架

复制代码
pip install fastapi uvicorn

3.代码撰写(用AI给你一个案例,现在按照我生成这个来演示)

复制代码
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List

# 创建FastAPI应用实例对象
app = FastAPI(
    title="简单FastAPI示例",
    description="这是一个基础的FastAPI应用示例",
    version="1.0.0"
)

# 定义数据模型
# 用户模型,(相当于强制数据类型)
class User(BaseModel):
    name: str
    id: int
    email: str

# 示例:创建一个 users 列表,存放 User 模型实例
#模拟数据库
users_list = [
    User(name="张三", id=1, email="zhangsan@example.com"),
    User(name="李四", id=2, email="lisi@example.com"),
    User(name="王五", id=3, email="wangwu@example.com"),
]

# 定义GET请求
# 获取所有用户
# 响应模型为 List[User],表示返回一个用户列表   返回的数据格式必须为 User 模型的格式
# 路径为 /users,HTTP 方法为 GET
# 函数 get_users 返回 users_list 列表
@app.get(path="/users",response_model=List[User])
def get_users():
    return users_list

# 定义POST请求
# 创建用户
# 请求模型为 User,响应模型也为 User   (提交的数据格式必须为 User 模型的格式)
# 路径为 /users,HTTP 方法为 POST
# 函数 create_users 接收一个 User 实例作为参数,将其添加到 users_list 列表中,并返回该实例
@app.post(path="/users",response_model=User)
def create_users(user:User):
    users_list.append(user)
    return user

# 定义PUT请求
# 更新用户
# 请求模型为 User,响应模型也为 User   (提交的数据格式必须为 User 模型的格式)
# 路径为 /users/{user_id},HTTP 方法为 PUT
# 函数 update_users 接收一个 User 实例作为参数,将其添加到 users_list 列表中,并返回该实例
@app.put(path="/users/{user_id}",response_model=User)
def update_users(user_id:int,user:User):
    for u in users_list:
        if u.id == user_id:
            u.name = user.name
            u.email = user.email
            return u
    return {"error": "User not found"}


# 定义DELETE请求
# 删除用户
# 请求模型为 User,响应模型也为 User   (提交的数据格式必须为 User 模型的格式)
# 路径为 /users/{user_id},HTTP 方法为 DELETE
# 函数 delete_users 接收一个 User 实例作为参数,将其从 users_list 列表中删除,并返回该实例
@app.delete(path="/users/{user_id}",response_model=User)
def delete_users(user_id:int):
    for u in users_list:
        if u.id == user_id:
            users_list.remove(u)
            return u
    return {"error": "User not found"}

#服务器启动器
# 当直接运行该脚本时,启动 FastAPI 应用
# 监听主机为 127.0.0.1,端口为 8001
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8001)

4.运行展示

最下方为URL,点击链接跳转本地浏览器;

因为我们并没有在129.0.0.1:8000这个URL配置任何东西,使用对于fastapi这个模版会给你返回josn格式的

复制代码
{
  "detail": "Not Found"
}

后台反馈:

下一步我们访问我们定义过的:127.0.0.1:8000/users

复制代码
[
  {
    "name": "张三",
    "id": 1,
    "email": "zhangsan@example.com"
  },
  {
    "name": "李四",
    "id": 2,
    "email": "lisi@example.com"
  },
  {
    "name": "王五",
    "id": 3,
    "email": "wangwu@example.com"
  }
]

后台反馈:

上面相当于运行代码的请求部分:

5.向服务器发送一个post请求

下面我们准备执行post操作,首先执行post我们的浏览器是不支持这种操作,需要借助三方工具:

postman;

因此我在网上找到一个在线工具: 在线Http接口调试工具 | 在线postman工具

下面是我代码的post请求设计:

以及接收数据格式:

在线工具页面:

操作重点:

1.将请求方式转换成post请求

2.输入对应URL及路径

3.选择application下的josn格式

4.数据格式必须按照定义的来

如图:

点击发送:

出现如下报错:

服务器端:

错误含义

  • OPTIONS /users :浏览器发送了一个OPTIONS类型的HTTP请求到/users端点

  • 405 Method Not Allowed :服务器不允许使用OPTIONS方法访问该端点

作者提问:为什么会发生这个错误?

这是 CORS(跨域资源共享) 机制导致的:

  1. 当浏览器从一个域名(如 http://localhost:3000 )访问另一个域名(如http://127.0.0.1:8001)的API时

  2. 浏览器会先发送一个 预检请求(OPTIONS请求) 来检查服务器是否允许跨域访问

  3. 如果服务器没有配置CORS或没有处理OPTIONS请求,就会返回405错误

解决方案:在FastAPI中添加CORS支持

配置CORS

app.add_middleware(

CORSMiddleware,

allow_origins=["*"], # 允许所有来源,生产环境应限制具体域名

allow_credentials=True,

allow_methods=["*"], # 允许所有HTTP方法

allow_headers=["*"], # 允许所有请求头

)

配置说明

  • allow_origins : 指定允许的域名, ["*"] 表示允许所有域名

  • allow_credentials : 是否允许发送cookie

  • allow_methods : 指定允许的HTTP方法

  • allow_headers : 指定允许的请求头

效果:添加CORS中间件后:

  • 浏览器的OPTIONS预检请求会得到正确响应

  • 跨域请求(如从React/Vue前端调用API)会正常工作

  • 不再出现405 Method Not Allowed错误

注意事项

  • 在生产环境中,不要使用 allow_origins=["*"] ,应该指定具体允许的域名

  • 只开放必要的方法和头信息,遵循最小权限原则

添加后并且导入相关库重启服务器:

复制代码
from fastapi.middleware.cors import CORSMiddleware

ok,再次发送post请求:

postman出现如下报错:

服务器后台没有报错

应该是格式有问题,重新换格式,不要中文的双引号:

成功发送:

服务器后台没有变化:

咱们再次回到查询页面看数据是否提交给服务器

完美,perfect!!

6.向服务器发送一个删除请求delete

来到postman页面编辑URL地址为127.0.0.1:8001/users/1

点击发送

postman页面:

再用postman发送查询请求

点击发送

OK,数据(id=1的数据被删除)

7.向服务器发送一个修改的请求方式(put)

相应代码:

原始数据

我现在要把刘德华的邮箱改成888

打开postman将URL修改还有请求体

点击发送成功

再用postman查询可得

成功,perfect!!

8.咱们访问服务器的客户端有几个?

两个:

我们浏览器和postman这两个客户端

作者提问:还有吗,还有其他的方式访问我的服务器吗

我的服务器是可以分辨是什么客户端发的请求:在请求投头中有一参数:User-Agent:我是谁

如果你用爬虫,你能在User-Agent这个地方直接说我是扒手吗,所以爬虫需要伪装成浏览器对服务器发起请求获得自己想要的资源。

curl:可以向服务器发送请求(操作系统自带的)

作者提问:curl是否组包向服务器发包。

向终端输入:

复制代码
url -i http://127.0.0.1:8000/users

返回了一个完整的响应命令:响应体+响应头+状态行

有点意思!

在终端用curl需要使用完整的请求包,详情请上网直接搜;

9.API文档

对于前后端分离:需要用API开发文档进行前后端数据交流。

之前手写,现在FastAPI提供API开发文档.

访问:

网址:http://127.0.0.1:8000/docshttp://127.0.0.1:8000/docs

简单FastAPI示例 - ReDochttp://127.0.0.1:8000/redoc

可以直接在网站上进行数据请求,交互式的,就可以不用postman和curl。非常牛逼。

两个都可以直接用,不是所有的都有,这就是FastAPI目前这么受欢迎的原因。

七、面试习题

一、选择题

  1. 在Python中,哪个库用于构建API接口?

答案:D. 以上都是

  1. 以下哪个HTTP方法用于获取资源?

答案:A. GET

  1. 在FastAPI中,如何定义一个GET请求的路由?

答案:D. @app.get("/path")

  1. 在FastAPI中,如何获取请求的JSON数据?

答案:D. request.json()

  1. 以下哪个状态码表示请求成功?

答案:A. 200

二、判断题

  1. FastAPI是一个用于构建API接口的Python框架。(对/错)

答案:对

  1. 在FastAPI中,路由函数的返回值会自动转换为JSON格式。(对/错)

答案:对

  1. FastAPI支持自动生成OpenAPI文档。(对/错)

答案:对

  1. 在FastAPI中,@app.post("/path")用于定义一个POST请求的路由。(对/错)

答案:错,应为@app.post("/path")而不是@app.post("/path", methods=["POST"])

  1. FastAPI不支持异步编程。(对/错)

答案:错

三、简答题

  1. 简述FastAPI的优势和特点。
  • 基于标准Python类型提示。

  • 支持异步请求处理。

  • 自动验证和文档(OpenAPI和JSON Schema)。

  • 基于Starlette和Pydantic。

  • 性能优异,与NodeJS和Go相当。

  • 简单、快速、安全。

  1. 在FastAPI中,如何定义请求体的模型?
  • 使用Pydantic模型定义请求体的结构,并使用`Body`参数从请求中提取数据。

示例代码:

复制代码
 from pydantic import BaseModel

   from fastapi import FastAPI, HTTPException

   app = FastAPI()

   class Item(BaseModel):

       name: str

       description: str = None

       price: float

       tax: float = None

   @app.post("/items/")

   async def create_item(item: Item):

       return item
  1. 如何在FastAPI中处理查询参数和路径参数?
  • 使用函数参数和类型注解来定义路径参数和查询参数。

示例代码:

复制代码
@app.get("/items/{item_id}")

   async def read_item(item_id: int, q: str = None):

       return {"item_id": item_id, "q": q}
  1. 如何在FastAPI中进行请求数据的验证?
  • 通过Pydantic模型自动验证请求数据,任何不符合模型的数据都会返回错误。

示例代码:

复制代码
  from pydantic import BaseModel, ValidationError

   class Item(BaseModel):

       name: str

       price: float

       is_offer: bool = None

   try:

       item = Item(**data)

   except ValidationError as e:

       raise HTTPException(status_code=422, detail=e.errors())
  1. 简述FastAPI的依赖注入机制。
  • FastAPI允许使用依赖注入来处理请求前和请求后的逻辑,如认证、数据库会话等。

  • 通过定义依赖函数并在路由函数中使用,可以重用代码并保持路由函数的简洁。

  • 依赖可以被缓存,通过添加`Depends`来实现。

示例代码:

复制代码
   from fastapi import Depends, HTTPException

   def get_db():

       db = SessionLocal()

       try:

           yield db

       finally:

           db.close()

   @app.get("/items/")

   async def read_items(db: Session = Depends(get_db)):

       items = db.query(Item).all()

       return items
相关推荐
小白学大数据2 小时前
某程旅行小程序爬虫技术解析与实战案例
爬虫·小程序
程序员agions2 小时前
Node.js 爬虫实战指南(四):反反爬策略大全,和网站斗智斗勇
爬虫·node.js
___波子 Pro Max.2 小时前
Python中Optional类型的作用解析
python
没学上了2 小时前
Pycharm修改环境
ide·python·pycharm
就这个丶调调2 小时前
Python中使用OpenAI实现AI问答:流式返回、记忆存储与工具调用详解
python·openai·流式响应·工具调用·ai问答·记忆存储
掘根2 小时前
【仿Muduo库项目】HTTP模块4——HttpServer子模块
网络协议·http·php
2301_764441332 小时前
python实现罗斯勒吸引子(Rössler Attractor)
开发语言·数据结构·python·算法·信息可视化
ipooipoo11882 小时前
如何判断动态IP池里的IP都是纯净的吗?
服务器·网络·tcp/ip
曲幽2 小时前
FastAPI数据库实战:从SQLAlchemy原理到高效连接管理,告别性能瓶颈
python·sqlite·flask·fastapi·web·sqlalchemy·db