asyncio 和 GET:意外的 UTF-8 BOM

asyncio and GET: Unexpected UTF-8 BOM

更新

我的 asyncio 驱动的 GET 请求程序今天给我一些问题,但仅限于它发出的某些 workItem 请求。

这不是导致问题的特定工作项。我可以检索单个 workItem,然后再次 运行 相同的函数并因错误而被拒绝:

Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0)

触发错误的行是:workItem = await resp.json() 在这个函数中:

async def getWorkItem(self, session, url):
    async with session.get(url, headers=headers) as resp:
        workItem = await resp.json()  <----------------- the problem
        workItem = pd.json_normalize(workItem['value'])
        workItem.columns = workItem.columns.str.replace(
            'fields.', '', regex=False)
        return workItem

我该如何解决这个解码问题?

您可以在解码 json 之前删除 BOM,一个最小的例子:

test.py:

import aiohttp
import asyncio
import json

async def main():
    async with aiohttp.ClientSession() as session:
        # async with session.get('http://127.0.0.1:9989/data.json') as resp:
        async with session.get('http://127.0.0.1:9989/with_bom.json') as resp:
            raw_text = await resp.text()
            text_without_bom = raw_text.encode().decode('utf-8-sig')
            work_items = json.loads(text_without_bom)
            print(type(work_items))
            print(work_items)

asyncio.run(main())

解释:

  1. 使用text()替换json()得到原始文本。
  2. 使用 utf-8-sig 解码删除 BOM
  3. 使用json.loads()str转换为dict

以上代码适用于有 BOM 或无 BOM 的响应。