【问题标题】:Issue with read_html when looping and reading from a dataframe循环和读取数据框时出现 read_html 问题
【发布时间】:2019-08-19 03:02:02
【问题描述】:

我有一个包含 100 行 URL 的数据框,我想从中抓取数据。如果我要复制其中一行中的 URL 并将其保存在变量 'url' 中,请执行以下操作:

 webpage <- read_html(url, encoding = "windows-874"). 

一切正常,但如果我要执行一个循环来调用数据框并逐行执行read_html,我会收到一个错误:

"UseMethod("read_xml") 中的错误:没有适用于 'read_xml' 的方法应用于类 "c('tbl_df', 'tbl', 'data.frame')""

我认为这与read_html 无法读取tibbles 的事实有关,但我无法找到解决方案。我尝试将输入read_html的URL的数据类型更改为字符、数字、向量等各种数据类型,但都没有解决问题。 您的帮助将不胜感激。

数据框“URLSetTrade”是从 csv 文件导入的,包含以下格式的数据行:

row1 -> 'https://www.settrade.com/AnalystConsensus/C04_10_stock_saa_p1.jsp?txtSymbol=wha&ssoPageId=9&selectPage=10'
row2 -> 'https://www.settrade.com/AnalystConsensus/C04_10_stock_saa_p1.jsp?txtSymbol=prm&ssoPageId=9&selectPage=10'
etc. etc.

读取网址的功能

getBatchAnalystData <- function(URLRow){
  url <- URLSetTrade[URLRow,1]
  webpage <- read_html(url, encoding = "windows-874") 
  target_price_html <- html_nodes(webpage,'td')
  target_price_data <- html_text(target_price_html)
  sub("-","",target_price_data)

为简单起见省略 AnalystPriceDataFrame

return(analystPriceDataFrame)
}

循环调用读取url函数

 for (i in 1:nrow(URLSetTrade)) {  assign(paste0(EarningDate2019_07_28_Cleaned[i,1],
  "AnalystData"),getBatchAnalystData(i))
    }

【问题讨论】:

  • 你的 row1 和 row2 是否包含相同的 url?它们应该是不同的网址吗?
  • 这两行之间的差异非常小。在第 1 行 -> txtSymbol=wha 和在第 2 行 -> txtSymbol=prm

标签: r rvest


【解决方案1】:

据我所知,xml2::read_html 要求其输入 x 是单个 url,而不是 url 的向量(长度为 2 或更多)。使用单个函数调用来读取多个 url 的一种方法是使用像 purrr::map 这样的函数。 purrr::map 将列表和函数(在我们的例子中为xml2::read_html)作为输入,并返回将函数应用于输入列表的每个元素的结果。如果您以前没有使用过,您可能需要从 CRAN 安装 purrr

mylist <- list("http://nytimes.com", "http://economist.com")
purrr::map(mylist, xml2::read_html)

根据您的问题,您似乎需要为 read_html 指定其他参数。您可以通过在对purrr::map 的调用中命名它们(及其值)来做到这一点。

purrr::map(mylist, xml2::read_html, encoding = "windows-874")

mylist 现在是您真正想要的网址列表(而不是我在上面粘贴的网址)。我希望这会有所帮助。

【讨论】:

  • 非常感谢弗雷德。您的解决方案完美无缺!!但是,既然 read_html 正在工作,那么错误就会传播到下一行。 “html_nodes(webpage,'td')”返回错误“UseMethod中的错误(“xml_find_all”):没有适用于“xml_find_all”的方法应用于类“list”的对象”我觉得这很奇怪,因为如果我要使用webpage
  • 我很高兴它成功了。 purrr::map() 的输出是一个列表,所以你需要这样处理它。在继续之前,您能否成功运行html_nodes(mylist[[1]], "td")。如果是,那么您应该能够将使用html_nodes 的行替换为对purrr::map() 的调用,例如purrr::map(htmls, html_nodes)。在您的代码中设置为“td”的参数的名称是什么?您需要将此参数及其名称添加到对 purrr::map` 的调用中。
  • 哦,我应该说我上面代码中的htmls,是purrr::map(mylist, xml2::read_html)的输出
  • 问题已解决。再次非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 2016-05-08
相关资源
最近更新 更多