如何在 R 中的 read_html 之后关闭未使用的连接

Posted

技术标签:

【中文标题】如何在 R 中的 read_html 之后关闭未使用的连接【英文标题】:How do I close unused connections after read_html in R 【发布时间】:2016-10-16 19:29:54 【问题描述】:

我对 R 很陌生,正在尝试访问 Internet 上的一些信息,但我遇到了似乎没有关闭的连接的问题。如果有人能给我一些建议,我将不胜感激......

最初我想使用 WebChem 包,理论上它可以提供我想要的一切,但是当网页中缺少某些输出数据时,WebChem 不会从该页面返回任何数据。为了解决这个问题,我从包中提取了大部分代码,但稍作修改以适应我的需要。这工作正常,大约前 150 次使用,但现在,虽然我什么都没做,但当我使用命令 read_html 时,我收到警告消息“关闭未使用的连接 4 (http:.....”虽然这只是一条警告消息,read_html 生成此警告后不返回任何内容。

我编写了一个简化的代码,如下所示。这有同样的问题

完全关闭 R(甚至重新启动我的电脑)似乎没有什么不同 - 现在我第二次使用该代码时会出现警告消息。我可以一次运行一个查询,在循环之外没有问题,但是一旦我尝试使用循环,第二次迭代就会再次发生错误。 我试图对代码进行矢量化,但它再次返回了相同的错误消息。 我尝试了 showConnections(all=TRUE),但只有 stdin、stdout、stderr 的连接数为 0-2。 我曾尝试寻找关闭 html 连接的方法,但我无法将 url 定义为 con,并且 close(qurl) 和 close(ttt) 也不起作用。 (分别返回没有适用于类“字符”对象的“关闭”方法和没有适用于类“c('xml_document','xml_node')”对象的“关闭”方法的错误)

有没有人知道关闭这些连接的方法,以免它们破坏我的日常工作?任何建议都会非常受欢迎。谢谢!

PS:我正在使用 R 版本 3.3.0 和 RStudio 版本 0.99.902。

CasNrs <- c("630-08-0","463-49-0","194-59-2","86-74-8","148-79-8")
tit = character()
for (i in 1:length(CasNrs))
  CurrCasNr <- as.character(CasNrs[i])
  baseurl <- 'http://chem.sis.nlm.nih.gov/chemidplus/rn/'
  qurl <- paste0(baseurl, CurrCasNr, '?DT_START_ROW=0&DT_ROWS_PER_PAGE=50')
  ttt <- try(read_html(qurl), silent = TRUE)
  tit[i] <- xml_text(xml_find_all(ttt, "//head/title"))

【问题讨论】:

在 R-3.2.5 (win10_64) 上,我既没有收到警告也没有收到错误。您可以在 R-3.2.5 中尝试一下,看看是否可以在那里重现它? 我在 OS X 上使用 R 3.3.0 并且没有错误。您还可以使用lapply%&gt;% 链接来进一步简化您的结构,尽管我怀疑它会对警告产生影响。 等等,你安装了curl吗?根据?read_html,如果已安装,它将使用curl(),否则使用url() 连接。两者都应该有效,真的,但值得一试。 感谢您的建议。我尝试了 R-3.2.5 中的代码,以及安装 curl 之后的代码。在这两种情况下,它都工作了一段时间,但经过几次迭代后,我再次遇到关闭连接错误。我还在代码中使用了 lapply 但没有任何成功 - 在这里我发布了循环以表明它适用于一次运行,而不是多次运行。 所以,我觉得有点奇怪,我可以手动单步执行循环并且一切正常,但是当我使用循环时,出现了连接错误——唯一的区别是我能多快手动单步执行循环。所以我尝试在 read_html 命令之后添加一个暂停(当前为 5 秒),现在循环也运行良好(如果非常慢)。似乎没有足够的时间正确关闭连接或类似的东西。无论如何,现在我可以在一夜之间运行该程序 - 这需要一段时间,但至少它不会崩溃!感谢您的帮助! 【参考方案1】:

在研究了该主题后,我想出了以下解决方案:

  url <- "https://website_example.com"
  url = url(url, "rb")
  html <- read_html(url)
  close(url)

# + Whatever you wanna do with the html since it's already saved!

【讨论】:

感谢您的回答!这对我来说是一种享受。【参考方案2】:

我还没有为这个问题找到一个好的答案。我想出的最好的解决方法是包含下面的函数,Secs = 3 或 4。我仍然不知道为什么会出现问题或如何在不产生很大延迟的情况下停止它。

CatchupPause <- function(Secs)
 Sys.sleep(Secs) #pause to let connection work
 closeAllConnections()
 gc()

【讨论】:

这也是我的解决方案,但似乎仍然找不到答案。真希望有一个用于 read_html 的 close() 函数【参考方案3】:

当我尝试在同一个脚本中抓取多个数据集时遇到同样的问题时,我发现了这篇文章。脚本会越来越慢,我觉得这是由于连接。这是一个关闭所有连接的简单循环。

for (i in seq_along(df$URLs))function(i)
  closeAllConnections(i)

【讨论】:

以上是关于如何在 R 中的 read_html 之后关闭未使用的连接的主要内容,如果未能解决你的问题,请参考以下文章

pd.read_html() 导入列表而不是数据框

如何在 Flutter 中的 navigator.pop(context) 之后显示小吃栏?

在 foreach R 中使用列表

R语言(XML/rvest)下载网页表格

如何运行使用旧版本包和最新 R 版本和包中的 R 编写的 R 脚本? [关闭]

如何在 R 中的 read.csv(或其他读取函数)中“关闭”科学记数法?