You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

aiohttp请求URL转义异常导致403错误问题排查

问题解决:aiohttp请求返回403,requests正常的原因与修复

问题背景

使用aiohttp库发送请求时返回403错误,但相同URL用requests库或浏览器访问可正常响应。抓包对比发现,两者请求头和参数几乎一致,仅x-signature参数存在差异:

  • requests发送的参数:x-signature=c52PtqjdBH%2FkUluVO79XQpC1fnw%3D
  • aiohttp发送的参数:x-signature=c52PtqjdBH/kUluVO79XQpC1fnw%3D

aiohttp自动将URL中已转义的%2F还原为/,这是导致服务器签名校验失败、返回403的核心原因。

原因分析

aiohttp基于yarl库处理URL,默认会对URL进行规范化操作,其中包括解码已转义的斜杠%2F。而requests库则保留了URL中的原始转义字符,不会自动解码。由于x-signature是服务器生成的签名参数,其中的%2F是签名的一部分,一旦被解码为/,服务器端的签名验证就会失败,从而返回403 Forbidden。

解决方案

通过yarl库手动构造URL,关闭自动解码%2F的功能,确保请求中的x-signature参数与原始URL完全一致:

import asyncio
import aiohttp
from yarl import URL

async def main():
    # 使用encoded=True保留URL中的原始转义字符
    target_url = URL(
        'http://p3-pc-sign.douyinpic.com/tos-cn-i-0813/dd367e76c9ea41ab9ee43b8f171e45aa~tplv-dy-aweme-images:q75.webp?x-expires=1691013600&x-signature=c52PtqjdBH%2FkUluVO79XQpC1fnw%3D&from=3213915784&s=PackSourceEnum_PUBLISH&se=false&sc=image&biz_tag=aweme_images&l=20230720060500934814BD78FB30518EED',
        encoded=True
    )
    async with aiohttp.ClientSession() as session:
        async with session.get(target_url, headers={
            'User-Agent': 'python-requests/2.31.0', 
            'Accept-Encoding': 'gzip, deflate', 
            'Accept': '*/*', 
            'Connection': 'close'
        }) as resp:
            print(resp.headers['Content-Type'])
            print(await resp.text())

asyncio.run(main())

验证效果

修改后,aiohttp发送的请求会完整保留x-signature中的%2F转义字符,与requests和浏览器的请求一致,服务器端的签名校验将通过,返回正常响应。

内容的提问来源于stack exchange,提问作者user13082750

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:16:35