【问题标题】:UTF-8 encoding problems with RR 的 UTF-8 编码问题
【发布时间】:2015-06-05 10:47:20
【问题描述】:

尝试解析来自墨西哥参议院的参议院声明,但遇到网页的 UTF-8 编码问题。

这个html很清楚:

library(rvest)
Senate<-html("http://comunicacion.senado.gob.mx/index.php/informacion/versiones/19675-version-estenografica-de-la-reunion-ordinaria-de-las-comisiones-unidas-de-puntos-constitucionales-de-anticorrupcion-y-participacion-ciudadana-y-de-estudios-legislativos-segunda.html")

这是网页的一个例子:

"CONTINÚA EL SENADOR CORRAL JURADO: Nosotros decimos. Entonces, bueno, el tema es que hay dos rutas señor presidente y también tratar, por ejemplo, de forzar ahora.   Una decisión de pre dictamen a lo mejor lo único que va a hacer es complicar más las cosas."

可以看出,重音和“ñ”都很好。

问题出现在其他一些 html 中(同一个域!)。例如:

 Senate2<-html("http://comunicacion.senado.gob.mx/index.php/informacion/versiones/14694-version-estenografica-de-la-sesion-de-la-comision-permanente-celebrada-el-13-de-agosto-de-2014.html")

我明白了:

 "-EL C. DIPUTADO ADAME ALEMÃÂN: En consecuencia está a discusión la propuesta. Y para hablar sobre este asunto, se le concede el uso de la palabra a la senadora…….."

在第二篇文章中,我尝试了 iconv() 并将 html() 上的编码参数强制为 encoding="UTF-8",但仍然得到相同的结果。

我还检查了使用 W3 Validator 的网页编码,它似乎是 UTF-8 并且没有问题。

使用 gsub 似乎效率不高,因为编码会下载具有相同“代码”的不同字符:

í - ÃÂ
á - ÃÂ
ó - ÃÂ

非常新鲜的想法。

> sessionInfo()
R version 3.1.2 (2014-10-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                           LC_TIME=English_United States.1252    

attached base packages:
[1] grDevices utils     datasets  graphics  stats     grid      methods   base     

other attached packages:
 [1] stringi_0.4-1    magrittr_1.5     selectr_0.2-3    rvest_0.2.0      ggplot2_1.0.0    geosphere_1.3-11 fields_7.1      
 [8] maps_2.3-9       spam_1.0-1       sp_1.0-17        SOAR_0.99-11     data.table_1.9.4 reshape2_1.4.1   xlsx_0.5.7      
[15] xlsxjars_0.6.1   rJava_0.9-6     

loaded via a namespace (and not attached):
 [1] bitops_1.0-6     chron_2.3-45     colorspace_1.2-4 digest_0.6.8     evaluate_0.5.5   formatR_1.0      gtable_0.1.2    
 [8] httr_0.6.1       knitr_1.8        lattice_0.20-29  MASS_7.3-35      munsell_0.4.2    plotly_0.5.17    plyr_1.8.1      
[15] proto_0.3-10     Rcpp_0.11.3      RCurl_1.95-4.5   RJSONIO_1.3-0    scales_0.2.4     stringr_0.6.2    tools_3.1.2     
[22] XML_3.98-1.1    

更新: 这似乎是问题:

stri_enc_mark(Senate2)
[1] "ASCII"  "latin1" "latin1" "ASCII"  "ASCII"  "latin1" "ASCII"  "ASCII"  "latin1"

...等等。显然,问题在于 latin1:

stri_enc_isutf8(texto2)
    [1]  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE

如何强制 latin1 更正 UTF-8 字符串?当 stringi “翻译”时它似乎做错了,给了我前面描述的问题。

【问题讨论】:

  • @Pascal:“我尝试了 iconv() 并将 html() 上的编码参数强制为 encoding="UTF-8",但仍然得到相同的结果。”

标签: html r text encoding utf-8


【解决方案1】:

我想我知道多米尼克的转折有什么作用。请参阅 Hadley 回答的 related topic here

您的问题几乎可以肯定是 UTF-8 文件带有a BOM 标记。 BOM 被引入 R 3.0.0 并且许多包不处理它们。通常的解决方法总是将文件保存在文本文件中,在处理 BOM 的程序中打开它,例如 Windows 记事本或 OpenOffice Calc,重新保存它,然后重新打开它。肮脏的技巧,但它可以重现,因为基础 R read.table / read.csv 系列现在可以明确地处理这个问题。

read.csv(..., fileEncoding = "UTF-8-BOM")    

我认为多米尼克的诡计与此有关。有人说 UTF-8-BOM 是一个遗留问题并且会消退,但我不这么认为,所以我认为如果有更明确的方法来解决这个问题会很棒。

您始终可以检查乱码的 UTF-8 是否在 OpenOffice Calc 中、在 Windows 上的记事本中正常工作,或者在 write.csv / read.csv 或其他文本写入/读取功能之后是否正常读取。

【讨论】:

    【解决方案2】:

    编码是 21 世纪最令人头疼的问题之一。但这里有一个解决方案:

    # Set-up remote reading connection, specifying UTF-8 as encoding.
    addr <- "http://comunicacion.senado.gob.mx/index.php/informacion/versiones/14694-version-estenografica-de-la-sesion-de-la-comision-permanente-celebrada-el-13-de-agosto-de-2014.html"
    read.html.con <- file(description = addr, encoding = "UTF-8", open = "rt")
    
    # Read in cycles of 1000 characters
    html.text <- c()
    i = 0
    while(length(html.text) == i) {
        html.text <- append(html.text, readChar(con = read.html.con,nchars = 1000))
        cat(i <- i + 1)
    }
    
    # close reading connection
    close(read.html.con)
    
    # Paste everything back together & at the same time, convert from UTF-8 
    # to... UTF-8 with iconv(). I know. It's crazy. Encodings are secretely 
    # meant to drive us insane.
    content <- paste0(iconv(html.text, from="UTF-8", to = "UTF-8"), collapse="")
    
    # Set-up local writing
    outpath <- "~/htmlfile.html"
    
    # Create file connection specifying "UTF-8" as encoding, once more
    # (Although this one makes sense)
    write.html.con <- file(description = outpath, open = "w", encoding = "UTF-8")
    
    # Use capture.output to dump everything back into the html file
    # Using cat inside it will prevent having [1]'s, quotes and such parasites
    capture.output(cat(content), file = write.html.con)
    
    # Close the output connection
    close(write.html.con)
    

    然后您就可以在您喜欢的浏览器中打开新创建的文件了。您应该可以看到它完好无损,并准备好使用您选择的工具重新打开它!

    【讨论】:

    • 我真的不知道为什么,但它就像一个魅力!谢谢!
    • 我希望我能告诉你我知道,但老实说,那个 iconv 扭曲,我只是不知道它是做什么的。它有效,从那里开始,我很高兴。 :D
    猜你喜欢
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 2017-12-22
    • 2011-11-08
    相关资源
    最近更新 更多