read_html编译错误

时间:2017-07-24 21:34:42

标签: r web-scraping rvest

我正在尝试网络搜索page。我想过使用rvest包。 但是,我陷入了第一步,即使用read_html来阅读内容。 这是我的代码:

library(rvest)
url <- "http://simec.mec.gov.br/painelObras/recurso.php?obra=17956"
obra_caridade <- read_html(url,
                        encoding = "ISO-8895-1")

我收到以下错误:

Error in doc_parse_raw(x, encoding = encoding, base_url = base_url, as_html = as_html,  : 
  Input is not proper UTF-8, indicate encoding !
Bytes: 0xE3 0x6F 0x20 0x65 [9]

我尝试使用类似的问题作为答案,但它没有解决我的问题:

obra_caridade <- read_html(iconv(url, to = "UTF-8"),
                        encoding = "UTF-8")

obra_caridade <- read_html(iconv(url, to = "ISO-8895-1"),
                        encoding = "ISO-8895-1")

两次尝试都返回了类似的错误。 有没有人对如何解决这个问题有任何建议? 这是我的会话信息:

R version 3.3.1 (2016-06-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

locale:
[1] LC_COLLATE=Portuguese_Brazil.1252  LC_CTYPE=Portuguese_Brazil.1252   
[3] LC_MONETARY=Portuguese_Brazil.1252 LC_NUMERIC=C                      
[5] LC_TIME=Portuguese_Brazil.1252    

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

other attached packages:
[1] rvest_0.3.2 xml2_1.1.1 

loaded via a namespace (and not attached):
[1] httr_1.2.1   magrittr_1.5 R6_2.2.1     tools_3.3.1  curl_2.6     Rcpp_0.12.11

1 个答案:

答案 0 :(得分:0)

出什么问题了?

您的问题是正确确定网页的编码。

好消息
因为您查看了源代码并找到了ISO-8895-1给出的元字符集,所以您的方法对我来说似乎是一种不错的方法。当然是ideal to be told the encoding,而不必依靠猜测。

坏消息
我不相信编码存在。首先,当我在线搜索时,搜索结果看起来像是错别字。其次,R通过iconvlist()为您提供了支持的编码列表。 ISO-8895-1不在列表中,因此将其作为read_html的参数输入是没有用的。我认为输入不支持的编码会发出警告会很好,但这似乎不会发生。

快速解决方案
正如@MrFlick在评论中建议的那样,使用encoding = "latin1"似乎有效。
我怀疑元字符集有错字,应该读ISO-8859-1(与latin1相同)。


猜测编码的提示

您的浏览器在做什么?
在浏览器中加载页面时,您可以see what encoding it is using来读取页面。如果页面看起来正确,这似乎是明智的猜测。在这种情况下,Firefox使用西方编码(即ISO-8859-1)。

使用R进行猜测

  1. rvest::guess_encoding是一个很好的用户友好功能,可以快速估算。您可以为函数提供网址,例如guess_encoding(url),或复制包含更复杂字符的短语,例如guess_encoding("Situação do Termo/Convênio:")
    关于此功能,需要注意的一件事是它只能从30种更常见的编码中进行检测,但是还有更多的可能性。

  2. 如前所述,iconvlist()提供了支持的编码列表。通过遍历这些编码并检查页面中的某些文本以查看是否符合我们的期望,我们应该以可能编码的清单作为结尾(并排除许多编码)。
    示例代码位于此答案的底部。

最终评论
以上所有指向ISO-8859-1的观点都是对编码的明智猜测。

页面网址包含一个.br扩展名,表示它是巴西语,以及-according to Wikipedia-此编码对巴西葡萄牙语具有完整的语言覆盖范围,这表明对于创建该网页的人来说,这可能不是一个疯狂的选择。我相信这也是一种相当普遍的编码类型。


代码

“用R猜测”第2点的示例代码(使用iconvlist()):

library(rvest)
url <- "http://simec.mec.gov.br/painelObras/recurso.php?obra=17956"

# 1. See which encodings don't throw an error
read_page <- lapply(unique(iconvlist()), function(encoding_attempt) {

  # Optional print statement to show progress to 1 since this can take some time
  print(match(encoding_attempt, iconvlist()) / length(iconvlist()))

  read_attempt <- tryCatch(expr=read_html(url, encoding=encoding_attempt),
                           error=function(condition) NA,
                           warning=function(condition) message(condition))
  return(read_attempt)
})

names(read_page) <- unique(iconvlist())

# 2. See which encodings correctly display some complex characters
read_phrase <- lapply(x, function(encoded_page) 
  if(!is.na(encoded_page))
    html_text(html_nodes(encoded_page, ".dl-horizontal:nth-child(1) dt")))

# We've ended up with 27 encodings which could be sensible...
encoding_shortlist <- names(read_phrase)[read_phrase == "Situação:"]