json Powershell调用-WebRequest和字符编码

v8wbuo2f  于 2022-12-01  发布在  Shell
关注(0)|答案(2)|浏览(136)

我试图通过Spotify的Web API从Spotify数据库中获取信息。但是,我遇到了重音元音的问题(ä,ö,ü等)。
以Tiësto为例,Spotify的API浏览器可以正确显示信息:https://developer.spotify.com/web-api/console/get-artist/?id=2o5jDhtHVPhrJdv3cEQ99Z
如果使用Invoke-Webrequest进行API调用,则会得到
蒂什托
作为名称:

function Get-Artist {
param($ArtistID = '2o5jDhtHVPhrJdv3cEQ99Z',
      $AccessToken = 'MyAccessToken')

$URI = "https://api.spotify.com/v1/artists/{0}" -f $ArtistID

$JSON = Invoke-WebRequest -Uri $URI -Headers @{"Authorization"= ('Bearer  ' + $AccessToken)} 
$JSON = $JSON | ConvertFrom-Json
return $JSON
}

如何获得正确的名称?

dgenwo3n

dgenwo3n1#

更新PowerShell (Core)7.3+现在默认为UTF-8,因为HTTP响应标头中缺少(有效的)charset属性,所以不再出现此问题。

Jeroen Mostert在对这个问题的评论中很好地解释了这个问题:
问题是Spotify(不明智地)没有返回它在标头中使用的编码。PowerShell遵循标准,假设ISO-8859-1,但不幸的是该网站使用的是UTF-8。(PowerShell应该忽略这里的标准,假设UTF-8,但这只是像,我的意见,伙计。)更多细节here,以及后续票据。
不需要使用临时文件的解决方法
假设已经定义了函数ConvertTo-BodyWithEncoding(见下文),则可以使用以下函数:

# ConvertTo-BodyWithEncoding defaults to UTF-8.
$JSON = Invoke-WebRequest -Uri $URI ... | ConvertTo-BodyWithEncoding
便利功能ConvertTo-BodyWithEncoding

注意事项:

  • 函数 manually 对组成给定响应主体的 raw bytes 进行解码,默认情况下为UTF-8,或者使用给定的编码(可以指定为[System.Text.Encoding]示例、* 代码页编号 *(例如1251)或编码 name(例如'utf-16le))。
  • 该函数也可用作an MIT-licensed Gist,并且只有后者将被继续维护。假设您已经查看了链接的代码以确保它是安全的(我个人可以向你保证,但你应该经常检查),您可以如下直接定义(将显示有关如何使函数在以后的会话中可用或将其转换为脚本的说明):
irm https://gist.github.com/mklement0/209a9506b8ba32246f95d1cc238d564d/raw/ConvertTo-BodyWithEncoding.ps1 | iex
function ConvertTo-BodyWithEncoding {

  [CmdletBinding(PositionalBinding=$false)]
  param(
    [Parameter(Mandatory, ValueFromPipeline)]
    [Microsoft.PowerShell.Commands.WebResponseObject] $InputObject,
    # The encoding to use; defaults to UTF-8
    [Parameter(Position=0)]
    $Encoding = [System.Text.Encoding]::Utf8
  )

  begin {
    if ($Encoding -isnot [System.Text.Encoding]) {
      try {
        $Encoding = [System.Text.Encoding]::GetEncoding($Encoding)
      }
      catch { 
        throw
      }
    }
  }

  process {
    $Encoding.GetString(
       $InputObject.RawContentStream.ToArray()
    )
  }

}
mec1mxoz

mec1mxoz2#

Jeron Mostert提供的解决方案解决了问题。您必须将其保存在文件中,并明确告诉Powershell它应该使用哪种编码。此解决方案对我很有效,因为我的程序可以花费任何时间(关于读/写IO)

function Invoke-SpotifyAPICall {
param($URI,
      $Header = $null,
      $Body = $null
      )

if($Header -eq $null) {
    Invoke-WebRequest -Uri $URI -Body $Body -OutFile ".\SpotifyAPICallResult.txt"    
} elseif($Body -eq $null) {
    Invoke-WebRequest -Uri $URI -Headers $Header -OutFile ".\SpotifyAPICallResult.txt"
}

$JSON = Get-Content ".\SpotifyAPICallResult.txt" -Encoding UTF8 -Raw | ConvertFrom-JSON
Remove-Item ".\SpotifyAPICallResult.txt" -Force
return $JSON

}

function Get-Artist {
    param($ArtistID = '2o5jDhtHVPhrJdv3cEQ99Z',
          $AccessToken = 'MyAccessToken')

    $URI = "https://api.spotify.com/v1/artists/{0}" -f $ArtistID

    return (Invoke-SpotifyAPICall -URI $URI -Header @{"Authorization"= ('Bearer  ' + $AccessToken)})
}

Get-Artist

相关问题