Powershell Invoke-WebRequest и кодировка символов

Я пытаюсь получить информацию из базы данных Spotify через их веб-API. Однако у меня возникают проблемы с ударными гласными (ä, ö, ü и т. д.)

Давайте возьмем Тиесто в качестве примера. Браузер API Spotify может правильно отображать информацию: https://developer.spotify.com/web-api/console/get-artist/?id=2o5jDhtHVPhrJdv3cEQ99Z

Если я сделаю вызов API с помощью Invoke-Webrequest, я получу

Ти??сто

как имя:

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
}

введите здесь описание изображения

Как я могу получить правильное имя?


person Solaflex    schedule 23.12.2017    source источник
comment
Проблема в том, что Spotify (неразумно) не возвращает кодировку, которую он использует в своих заголовках. PowerShell подчиняется стандарту, предполагая ISO-8859-1, но, к сожалению, сайт использует UTF-8. (PowerShell здесь следует игнорировать стандарты и использовать кодировку UTF-8, но, по моему мнению, это то же самое, чувак.) Подробнее здесь вместе с последующим билетом. Возможные обходные пути здесь (но, к сожалению, они предполагают отказ от Invoke-WebRequest).   -  person Jeroen Mostert    schedule 23.12.2017
comment
Спасибо Джероен. Я уже ожидал этого. Однако я предполагал, что Invoke-WebRequest будет иметь для этого параметр. Я попробую ваш обходной путь. скоро сообщим.   -  person Solaflex    schedule 23.12.2017


Ответы (2)


Jeroen Mostert в комментарии к вопросу хорошо объясняет проблему:

Проблема в том, что Spotify (неразумно) не возвращает кодировку, которую он использует в своих заголовках. PowerShell соответствует стандарту, предполагая ISO-8859-1, но, к сожалению, сайт использует кодировку UTF-8. (PowerShell здесь следует игнорировать стандарты и использовать кодировку UTF-8, но, по моему мнению, это то же самое, чувак.) Подробнее здесь вместе с последующим билетом.

Временное решение, не требующее использования временных файлов, заключается в перекодировании неправильно прочитанной строки.

Если предположить наличие функции convertFrom-MisinterpretedUtf8, то можно использовать следующее:

$JSON = convertFrom-MisinterpretedUtf8 (Invoke-WebRequest -Uri $URI ...)

См. ниже определение функции.


Вспомогательная функция convertFrom-MisinterpretedUtf8:

function convertFrom-MisinterpretedUtf8([string] $String) {
  [System.Text.Encoding]::UTF8.GetString(
     [System.Text.Encoding]::GetEncoding(28591).GetBytes($String)
  )
}

Функция преобразует неправильно прочитанную строку обратно в байты на основе ошибочно примененной кодировки (ISO-8859-1), а затем воссоздает строку на основе фактической кодировки (UTF-8).

person mklement0    schedule 24.12.2017

Проблема решена с помощью обходного пути, предоставленного Джероном Мостертом. Вы должны сохранить его в файл и явно указать Powershell, какую кодировку он должен использовать. Этот обходной путь работает для меня, потому что моя программа может занять столько времени, сколько ей нужно (относительно чтения/записи ввода-вывода)

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
person Solaflex    schedule 23.12.2017