Flutter http response.body 错误的 utf8 编码

Gui*_*mao 15 html http utf-8 flutter

我开始学习 Flutter,并通过制作自己的manga阅读应用程序来实现这一目标,在该应用程序中,我从我最常使用的网站上抓取所有数据。

\n\n

我的问题是,由于此错误,只有我读到的其中一篇mangas无法抓取数据:

\n\n
FormatException (FormatException: Bad UTF-8 encoding 0x22 (at offset 369))\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的爬虫代码

\n\n
    Future<Manga> getMangaInfo(source) async{\n    final response =  await _client.get(source);\n    var manga;\n    print(response.body);//error occurs here\n    final document = parse(response.body);\n\n    final mangaInfo = document.getElementsByClassName(\'tamanho-bloco-perfil\');\n    for(Element infos in mangaInfo){\n      final infoCont = infos.getElementsByClassName(\'row\');\n      //get titulo\n      Element tituloCont = infoCont[0];\n      final tituloH = tituloCont.getElementsByTagName(\'h2\');\n      Element tituloCont2 = tituloH[0];\n      String titulo = \'[\'+tituloCont2.text+\']\';\n      //print(titulo);\n\n      //get capa\n\n      Element capaCont = infoCont[2];\n      final capaImg = capaCont.getElementsByTagName(\'img\');\n      Element capaCont2 = capaImg[0];\n      final capaUrl = capaCont2.attributes[\'src\'];\n\n      //get caprecente\n      final capsPorNumero = document.getElementsByClassName(\'row lancamento-linha\');\n      final caps = capsPorNumero[0].getElementsByTagName(\'a\');\n      Element info = caps[0];\n      final numero = info.text.split(\' \')[1];\n      final capRecenteUrl = info.attributes[\'href\'];\n\n      manga = Manga(null,source,titulo,capaUrl,numero,capRecenteUrl);\n\n\n    }\n    return manga;\n\n  }\n
Run Code Online (Sandbox Code Playgroud)\n\n

response.body给出错误的

\n\n

我也尝试过使用response.bodyBytes和解码但仍然无法修复它

\n\n

这是该页面的链接:\n https://unionleitor.top/perfil-manga/kimetsu-no-yaiba

\n\n

我猜问题是 html 头部以下元标记上的 \xef\xbf\xbd 字符

\n\n
<meta name="description" content="Kimetsu no Yaiba - Novo mang\xc3\xa1 sobrenatural da Shonen Jump. O mang\xc3\xa1 conta a hist\xc3\xb3ria de Tanjiro, o filho mais velho de uma fam\xc3\xadlia que \xef\xbf\xbd">\n
Run Code Online (Sandbox Code Playgroud)\n\n

我还没有找到解决方案,也许我只是找错了地方。\n任何人都可以帮助我解决这个问题吗?
谢谢!

\n

Kev*_*lvo 48

我只是做:

utf8.decode(response.bodyBytes);
Run Code Online (Sandbox Code Playgroud)

即使你得到的是 JSON

jsonDecode(utf8.decode(response.bodyBytes))
Run Code Online (Sandbox Code Playgroud)

  • 奇迹般有效。OP 应该将此标记为已接受的答案。 (2认同)

Mik*_*fik 2

解决方案1

\n\n

没有定义的字符集的 HTTP 假定以 ISO-8859-1 (Latin-1) 进行编码。其描述中的正文与此行为一致。\n如果服务器响应将 Content-Type 标头设置为 application/json; charset=utf-8 正文应该按预期工作。

\n\n

当然,问题是有些服务器没有为 JSON 设置字符集(这是有效的),但这也是两个规范之间的一个灰色区域:

\n\n

JSON 始终应该是 UTF-8,因此表示您不需要设置字符集,但是 ..\nHTTP 始终默认为 ISO-8859-1,除非显式设置字符集。\nA "智能”HTTP 客户端可以选择遵循比 HTTP 定义更接近的 JSON 定义,并简单地说任何 application/json 默认情况下都是 UTF-8 - 技术上违反了 HTTP 标准。\n但是,最可靠的解决方案最终是让服务器显式地说明根据两个标准都有效的字符集。

\n\n
  HttpClientRequest request = await HttpClient().post(_host, 4049, path) /*1*/\n    ..headers.contentType = ContentType.json /*2*/\n    ..write(jsonEncode(jsonData)); /*3*/\n  HttpClientResponse response = await request.close(); /*4*/\n  await response.transform(utf8.decoder /*5*/).forEach(print);\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

解决方案2(颤振)

\n\n

使用replaceAll替换response.body

\n\n
newString.replaceAll(\'\xef\xbf\xbd\', \'\');\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

解决方案3(php)

\n\n

首先使用 php 文件获取内容,然后使用您的 url\n 并使用 str_replace php

\n\n
       $curlSession = curl_init();\n        curl_setopt($curlSession, CURLOPT_URL, \'YOUR-URL\');\n        curl_setopt($curlSession, CURLOPT_BINARYTRANSFER, true);\n        curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true);\n\n        $jsonData = curl_exec($curlSession);\necho $bodytag = str_replace("\xef\xbf\xbd", "", $jsonData);\n\n        curl_close($curlSession);\n
Run Code Online (Sandbox Code Playgroud)\n\n

希望能帮助到你。

\n