Python发送POST请求到FastAPI Selenium爬虫服务返回422错误如何解决
问题原因
422是FastAPI的参数验证错误,你的服务端路由函数中的website是基础字符串类型,FastAPI默认会将这类参数识别为URL查询参数,而你客户端是把URL直接放在POST请求体中提交,服务端找不到对应参数就会返回422错误。
解决方案
推荐使用JSON格式传输参数,修改方式如下:
1. 客户端修改
将POST请求的传参方式从data改为json,传递结构化键值对:
# 把原来的post请求行替换成下面的代码 r = requests.post(SCRAPER_API_ENDPOINT, json={"website": website}, headers=headers)
2. 服务端修改,二选一即可
方案A:使用Body注解接收参数(快速修改)
先从fastapi导入Body,再修改路由函数参数:
# 导入新增 from fastapi import Body # 修改路由函数参数 async def prediction_view(website: str = Body(embed=True), authorization = Header(None), settings:Settings = Depends(get_settings)):
方案B:用Pydantic模型做参数校验(更规范)
先定义请求模型,再替换路由参数:
# 导入新增 from pydantic import BaseModel # 新增请求模型 class ScrapeRequest(BaseModel): website: str # 修改路由函数参数 async def prediction_view(request: ScrapeRequest, authorization = Header(None), settings:Settings = Depends(get_settings)): # 函数内部调用的地方改成request.website driver.get(request.website)
额外优化建议
你当前的服务端代码每次请求都会新建Chrome实例且没有销毁,很容易出现资源泄漏导致容器崩溃,建议补充资源回收逻辑:
@app.post("/") async def prediction_view(request: ScrapeRequest, authorization = Header(None), settings:Settings = Depends(get_settings)): verify_auth(authorization, settings) driver = None try: options = webdriver.ChromeOptions() options.headless = True options.add_argument("--headless=new") options.add_argument('--no-sandbox') options.add_argument('--disable-gpu') options.add_argument('--disable-dev-shm-usage') # 适配Docker环境,避免Chrome崩溃 driver = webdriver.Chrome("/usr/local/bin/chromedriver", options=options) wait = WebDriverWait(driver, 10) driver.get(request.website) title = "Sorry, we failed to get the correct name" try: title = driver.find_element(By.XPATH, "//title") title = title.get_attribute("innerText") except: pass return{"results": title, "original": title} finally: if driver: driver.quit() # 强制关闭Chrome实例,回收资源
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

