【问题标题】:warning xml_find_all.xml_node while webscrape with rvest使用 rvest 进行网络抓取时警告 xml_find_all.xml_node
【发布时间】:2020-08-28 05:20:34
【问题描述】:

我想从这个link 中抓取数据。我使用 rvest 和循环来获取表格。

这是我的代码:

require(dplyr)
require(rvest)

# store web url
url <- "https://corona.thueringen.de/covid-19-bulletin/"
# check xpath
xpath_part1="/html/body/main/div[2]/div/section[2]/ul/li["
xpath_part2="]/div/div/div[2]/div/table"

# save tables
for(i in 1:50){
  tbl_test_ <- 
    url %>% 
    xml2::read_html() %>%
    rvest::html_nodes(xpath=paste0(xpath_part1, i, "]", xpath_part2)) %>%
    rvest::html_table(fill = TRUE) %>%
    dplyr::rename(Gesundheitsamt=1)
}

我收到以下错误:

Fehler in UseMethod("rename_") : 
  nicht anwendbare Methode für 'rename_' auf Objekt der Klasse "list" angewendet
Zusätzlich: Warnmeldung:
In xml_find_all.xml_node(x, make_selector(css, xpath)) :
  Invalid expression [1207]

编辑1:

我已经清理了我的代码:

# save tables
for(i in 1:50){
  tbl_test_ <- 
    url %>% 
    xml2::read_html() %>%
    rvest::html_nodes(xpath=paste0(xpath_part1, i, xpath_part2)) %>%
    rvest::html_table(fill = TRUE) %>%
    dplyr::rename(Gesundheitsamt=1)
}

并得到错误信息:

Fehler in open.connection(x, "rb") : HTTP error 404.

有关如何纠正此错误并获取表格的任何建议?

编辑 2: 在当前表中,我可以添加一些附加信息。我得到了这个:

# store web url
url <- "https://corona.thueringen.de/bulletin"
#Read the page
page <- url %>%  read_html()

fxp <- "/html/body/main/div[2]/div/section[1]/div[2]/div[1]/div[2]/div"

tbl_current <- 
  page %>% 
  html_nodes("table[align=left]") %>% 
  html_table() %>% 
  .[[1]] %>%
  dplyr::rename(Gesundheitsamt=1) %>% 
  dplyr::mutate(note_1=rvest::html_text(rvest::html_nodes(th_bulletin, xpath=paste0(fxp, "/div[1]/h2")))) %>% 
  dplyr::mutate(note_2=rvest::html_text(rvest::html_nodes(th_bulletin, xpath=paste0(fxp, "/div[3]/h3"))))

使用完整的 xpath 不是最好的方法,但我不知道只从站点的特定部分获取节点 (/html/body/main/div[2]/div/section1 )。

对于已归档的表格,我也在寻找这些信息。我最初尝试将其存储在列表中。但这似乎只适用于一个 html_node。

tbl_all <-
page %>%
  rvest::html_nodes("table[align=left]")

这里我得到一个列表,每个表都有一个元素

[[1]] table
[[2]] table
.
.
.

使用多个节点是不行的。

tbl_all_ <-
  page %>%
  rvest::html_nodes("table[align=left]", "h2", "h3")

可以在一个列表中获得一种以上的节点吗?我想得到

[[1]] for /html/body/main/div[2]/div/section[2]/ul/li[1]
table 1
table 2
h2
h3
[[2]] for /html/body/main/div[2]/div/section[2]/ul/li[2]
table 1
table 2
h2
h3
[[3]] for /html/body/main/div[2]/div/section[2]/ul/li[3] ...

提前致谢。

【问题讨论】:

  • 我认为您在选择器中有一个额外的括号 (])。看起来paste0(xpath_part1, i, "]", xpath_part2) 返回两个右括号。如果您在 paste0 函数中添加方括号而不是 xpath 变量,则可能更易于管理:paste0(xpath_part1, "[", i, "]", xpath_part2)
  • 我已经删除了多余的括号。现在还有另一个错误(HTTP 错误 404)。好像没有网站,但我可以看到网站...
  • 是的,我也看到了。基本 url 返回 404 错误。也许该页面暂时不可用或路径已更改?希望它没有被删除。
  • 对,好像改成了:https://corona.thueringen.de/bulletin

标签: r for-loop web-scraping rvest


【解决方案1】:

这是检索请求表的更简单方法。
无需单独检索每个表,而是读取一次页面(速度更快,网络流量更少),然后使用 html_nodes 和 CSS 'table' 选择器解析所有表。
这将返回页面上的所有 142 个表。看起来这些表是 3 个一组的。通过使用 CSS 选择器指定所需的属性,可以减少此列表以提供所需的子集。

require(dplyr)
require(rvest)

# store web url
url <- "https://corona.thueringen.de/bulletin"
#Read the page
page <- url %>%  read_html() 
#retrieve all of the tables
tables<- page %>% rvest::html_nodes("table")

#cycle through the selected tables
#and stored as needed
for (table in tables) {
  print(table %>% html_table())
  Sys.sleep(2)
}

#another possible selection method:
# select tables where the align attribute = "left"
page %>% html_nodes("table[align=left]") %>% html_table()

更新
由于您正在查找作为列表存储在列表中的所有表。这是一个修订版。该页面被分解为一系列 li 与 class="th-lst-itm card"。第一步是检索这个父节点列表,然后解析每个父节点的所有表。

# store web url
url <- "https://corona.thueringen.de/bulletin"
#Read the page
page <- url %>%  read_html() 

#find archived list items with class=th-lst-itm
listofitems<-page %>% rvest::html_nodes("li.th-lst-itm")

#store all of the tables in as list within a list
answer<-lapply(listofitems, function(item){
  item %>% html_nodes("table") %>% html_table()
})

# #first try but did not work for all elements
# names(answer)<-listofitems %>% html_node("h2") %>% html_text() %>% trimws()

#name the elements
names(answer)<-listofitems %>% html_node("span.th-lbl") %>% html_text() %>% trimws() 

#Pull a sample
answer[["COVID-19 / Bulletin der Thüringer Landesregierung 02/2020" ]]

【讨论】:

  • 现在可以获取表格了。我尝试在表格中添加一些附加信息,但这并不容易。当我可以将不同的节点存储在列表中时,也许会更容易。是否可以获得不同的节点,例如 html_nodes("table[align=left]", "h2", "h3")?但这不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
  • 2015-11-07
相关资源
最近更新 更多