Pregunta convertir la codificación de la entidad de caracteres HTML en R


¿Hay alguna forma en R para convertir codificaciones de entidades de caracteres HTML?

Me gustaría convertir entidades de caracteres HTML como & a & o > a >

Para Perl existe el paquete HTML :: Entidades que podría hacer eso, pero no pude encontrar algo similar en R.

También intenté iconv() pero no pudo obtener resultados satisfactorios. Tal vez también hay una forma de usar el XML pero aún no lo he descubierto.


17
2018-02-20 21:15


origen


Respuestas:


Actualizar: esta respuesta está desactualizada Por favor, checa el Responda abajo basado en el nuevo paquete xml2.


Pruebe algo como:

# load XML package
library(XML)

# Convenience function to convert html codes
html2txt <- function(str) {
      xpathApply(htmlParse(str, asText=TRUE),
                 "//body//text()", 
                 xmlValue)[[1]] 
}

# html encoded string
( x <- paste("i", "s", "n", "&", "a", "p", "o", "s", ";", "t", sep = "") )
[1] "isn&apos;t"

# converted string
html2txt(x)
[1] "isn't"

ACTUALIZACIÓN: Editó la función html2txt () por lo que se aplica a más situaciones


18
2018-02-20 21:34



Unescape xml / html valores utilizando xml2 paquete:

unescape_xml <- function(str){
  xml2::xml_text(xml2::read_xml(paste0("<x>", str, "</x>")))
}

unescape_html <- function(str){
  xml2::xml_text(xml2::read_html(paste0("<x>", str, "</x>")))
}

Ejemplos:

unescape_xml("3 &lt; x &amp; x &gt; 9")
# [1] "3 < x & x > 9"
unescape_html("&euro; 2.99")
# [1] "€ 2.99"

16
2018-02-03 21:21



Mientras que la solución de Jeroen hace el trabajo, tiene la desventaja de que no se vectoriza y, por lo tanto, es lento si se aplica a una gran cantidad de caracteres. Además, solo funciona con un vector de caracteres de longitud uno y uno tiene que usar sapply para un vector de caracteres más largo.

Para demostrar esto, primero creo un gran vector de caracteres:

set.seed(123)
strings <- c("abcd", "&amp; &apos; &gt;", "&amp;", "&euro; &lt;")
many_strings <- sample(strings, 10000, replace = TRUE)

Y aplica la función:

unescape_html <- function(str) {
  xml2::xml_text(xml2::read_html(paste0("<x>", str, "</x>")))
}

system.time(res <- sapply(many_strings, unescape_html, USE.NAMES = FALSE))
##    user  system elapsed 
##   2.327   0.000   2.326 
head(res)
## [1] "& ' >" "€ <"   "& ' >" "€ <"   "€ <"   "abcd" 

Es mucho más rápido si todas las cadenas en el vector de caracteres se combinan en una cadena única y grande, de tal manera que read_html() y xml_text() solo necesita ser usado una vez Las cuerdas se pueden separar fácilmente de nuevo usando strsplit():

unescape_html2 <- function(str){
  html <- paste0("<x>", paste0(str, collapse = "#_|"), "</x>")
  parsed <- xml2::xml_text(xml2::read_html(html))
  strsplit(parsed, "#_|", fixed = TRUE)[[1]]
}

system.time(res2 <- unescape_html2(many_strings))
##    user  system elapsed 
##   0.011   0.000   0.010 
identical(res, res2)
## [1] TRUE

Por supuesto, debe tener cuidado de que la cadena que usa para combinar varias cadenas de caracteres str ("#_|" en mi ejemplo) no aparece en ninguna parte str. De lo contrario, introducirás un error cuando la cadena grande se vuelva a dividir al final.


0
2017-08-13 18:40