El texto de respuesta de solicitud de XHR tiene un juego de caracteres inesperado

Estaba viendo la respuesta, por @OmegaStripes, a esta pregunta ¿Cómo obtener un texto interno particular de una clase específica? Aquí uno usa la función Split , y una cadena de delimitador específica, para extraer un href de .responseBody .

Luego traté de replicar esto para extraer el siguiente href :

 "https://www.england.nhs.uk/statistics/wp-content/uploads/sites/2/2018/02/New-AmbSYS-to-2018-Jan.csv" 

de los indicadores de calidad de ambulancia de NHS England

Fragmento de HTML:

  

Ambulance Quality Indicators

Problema:

Recibo un mensaje de respuesta que se ve de la siguiente manera:

Ejemplo de texto de respuesta:

Texto de respuesta

A partir de una investigación rápida, ver referencias, supongo que este es quizás un problema de encoding.

Intenté configurar un .SetRequestHeader

  .setRequestHeader "Content-Type", _ "application/x-www-form-urlencoded; charset=UTF-8" 

Esto no hizo diferencia en la salida.

Para ser sincero, no tengo ni idea de cómo resolver esto.

¿Alguna sugerencia, por favor, sobre cómo obtengo el texto de respuesta esperado? es decir, que puedo analizar el href de interés.

Contexto:

Esto es parte de un trabajo más grande donde:

1) Quiero borrar ese enlace CSV (cuyo nombre cambiará cada mes), sin tener el navegador emergente

2) Descarga el contenido del archivo de destino

3) Use ADODB.Stream para escribir el archivo binario.

Este proceso fue descrito por @OmegaStripes en respuesta a mi pregunta Return focus to ThisWorkbook.Activesheet después de la descarga del archivo XMLHTTP60 . Estoy tratando de comprender e implementar esa sugerencia actualmente.

Código:

 Option Explicit Public Const url As String = "https://www.england.nhs.uk/statistics/statistical-work-areas/ambulance-quality-indicators/" Public aBody As String Sub Testing() ' Download via XHR With CreateObject("MSXML2.XMLHTTP") .Open "GET", url, False .setRequestHeader "Content-Type", "application/x-www-form-urlencoded; charset=utf-8" .send ' Get binary response content aBody = .responseBody End With ActiveSheet.Range("A1") = aBody End Sub 

Referencias

1) XMLHTTP y caracteres especiales (por ejemplo, acentos)

2) Método setRequestHeader (IXMLHTTPRequest)

3) VBA HTML Scraping – ‘.innertext’ de la tabla compleja

4) problemas Msxml2.ServerXMLHTTP y UTF-8 charset

Así que el crédito va a @FlorentB para esta solución y un agradecimiento a @OmegaStripes por la sugerencia.

Como se sugirió, el problema era que .responseBody estaba devolviendo una matriz de bytes codificados como UTF-8. Como se señaló, lo estaba convirtiendo en una cadena (encoding UTF-16) por lo tanto, todos estos caracteres extranjeros.

Utilicé la función BytesToString @ Tomalak, con cambios menores, para manejar la conversión a cadena.

Código:

 Option Explicit Public Const url As String = "https://www.england.nhs.uk/statistics/statistical-work-areas/ambulance-quality-indicators/" Public aBody As String 'this is causing the conversion Const adTypeBinary As Byte = 1 Const adTypeText As Byte = 2 Const adModeReadWrite As Byte = 3 Public Const strPath As String = "C:\Users\User\Desktop\testXMLHTTPOutput" Public Sub Testing() ' Download via XHR With CreateObject("MSXML2.XMLHTTP") .Open "GET", url, False .send ' Get binary response content aBody = BytesToString(.responseBody, "UTF-8") End With Dim fso As Object 'late binding Set fso = CreateObject("Scripting.FileSystemObject") Dim oFile As Object Set oFile = fso.CreateTextFile(strPath) oFile.WriteLine aBody oFile.Close Set fso = Nothing Set oFile = Nothing End Sub 'ADODB.Stream with stream.CharSet = "UTF-8" 'http://msdn.microsoft.com/en-us/library/windows/desktop/ms675032%28v=vs.85%29.aspx Public Function BytesToString(ByVal bytes As Variant, ByVal charset As String) As String With CreateObject("ADODB.Stream") .Mode = adModeReadWrite .Type = adTypeBinary .Open .Write bytes .Position = 0 .Type = adTypeText .charset = charset BytesToString = .ReadText End With End Function 

Otro enlace útil aquí:

Guarde el archivo de texto UTF-8 codificado con VBA