如何使用 rvest 正确识别要解析的特定值
how to properly identify specific value to parse using rvest
亲爱的集体智慧
我正在努力尝试使用 rvest 从 https://www.1944.pl/powstancze-biogramy,ord,nazwisko,0,strona,1.html
中解析 table
我需要遍历 table 的所有节点并一一提取其值。然后迭代到下一页并重复。
我打算单独读取 table 值,因为我需要在代码中添加一个变体循环 - 对于每一行,如果“Data urodzenia”列中的值等于“-”,则程序应输入与该行对应的网页并提取其他值(标记为“Rocznik”)。
目前,我无法强制 rvest 从 table 中读取值。我想我不太遵循 html 选择器的想法...我可以使用以下函数中的 (".museumTableRow") 标签阅读整个 table (每页) :
library(rvest)
library(tidyverse)
page <- read_html("https://www.1944.pl/powstancze-biogramy,ord,nazwisko,0,strona,1.html")
getPage <- function(html){
html %>%
html_nodes(".museumTableRow") %>%
html_text() %>%
str_trim() %>%
unlist()
}
Append_page <- getPage(page)
...但是当我尝试对 table 的特定单元格使用选择器时,我得到一个空的(“字符(0)”)响应。我试图通过手动检查页面并按照库创建者的建议使用 selectorgadget 插件来查找相关标签。这些看起来很奇怪(对我来说),例如。对于“Nazwisko”列中的名字,selectorgadget 建议:
".footable-even:nth-child(1) .footable-第一列.museumTableRow"
所以我也试着和他们一起玩,但我没有成功。我想我不完全理解它是如何工作的。对于如何强制 rvest 逐个单元格读取此 table 并将后续单元格中的值附加到 data.table.
的任何建议,我将不胜感激
我希望这足够具体。
这应该有效:
library(glue)
page <- read_html("https://www.1944.pl/powstancze-biogramy,ord,nazwisko,0,strona,1.html")
dat <- page %>% html_elements(css="tbody tr")
txt <- dat %>% html_text()
hrefs <- dat %>% html_element("a") %>% html_attr("href")
s <- lapply(1:length(txt), function(i)trimws(strsplit(txt[i], split="\n")[[1]]))
out_txt <- t(sapply(s, function(x)x[which(x != "")]))
stem <- "https://www.1944.pl"
for(i in 1:nrow(out_txt)){
if(out_txt[i,6] == "-"){
u <- paste0(stem, hrefs[i])
h <- read_html(u)
btxt <- h %>% html_elements(css="div.biogram--info div.tag") %>% html_text()
ind <- grep("Rocznik", btxt)
if(length(ind) > 0){
btxt2 <- h %>% html_elements(css=glue("div.biogram--info div.info")) %>% html_text()
out_txt[i,6] <- btxt2[ind]
}else{
out_txt[i,6] <- NA_character_
}
}
}
head(out_txt)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7]
# [1,] "Abajew" "Aleksander" "-" "-" "-" "1916-06-06" "-"
# [2,] "Abakanowicz" "Piotr" "-" "-" "\"Grey\"" "1890-06-21" "1948-06-01"
# [3,] "Abakanowicz" "Maria" "-" "-" "\"Lena\"" "1901" "-"
# [4,] "Abczyńska" "Alicja" "Henryka" "sanitariuszka" "\"Ciocia Stasia\"" "1900-02-09" "1989-04-26"
# [5,] "Abczyńska" "Janina" "-" "pielęgniarka" "\"Julia\"" "1883-06-15" "1944-08-30"
# [6,] "Abczyński" "Stanisław" "-" "-" "\"Stefan\"" NA "-"
在上面的代码中,它获取了行中第一个 <a>
标签的数据和 href。如果第 i 行的第 6 列是 "-"
,它就会转到该引用。如果有一个标记为 "Rocznik"
的条目,如果存在则获取年份,否则用缺失值替换该条目。
编辑:关于 CSS 选择器的详细信息
我假设 stem <- "https://www.1944.pl"
部分之前的所有内容都非常简单,因为它或多或少都遵循您已经走的路。那么,让我们深入研究 for
循环以及它们是如何工作的。正如您所指出的,最初第三行在第六列中有一个 "-"
作为其条目,这应该会触发另一次查找。所以,这意味着应该遵循第三个 href:
hrefs[3]
# [1] "/powstancze-biogramy/maria-abakanowicz,845.html"
为此,我们可以将其粘贴到之前定义的 stem
上以生成有效的 URL,我们将其读入 h
。如果您在浏览器中访问 URL,您会看到:
您希望能够识别与“Rocznik”关联的号码。如果您 right-click 选择“Rocznik”一词并选择“检查”,您将看到:
您会注意到所有条目都在 <div>
和 class "biogram--info"
中。此外,每个条目的标题都在 <div>
和 class "tag"
中。我编辑了上面的答案,通过使用 "tag"
div 使结果更清晰一些。 btxt
的结果如下所示:
btxt <- h %>%
html_elements(css="div.biogram--info div.tag") %>%
html_text()
btxt
# [1] "Pseudonim:"
# [2] "Data urodzenia:"
# [3] "Data śmierci:"
# [4] "Funkcja:"
# [5] "Rocznik:"
# [6] "Stopień:"
# [7] "Pseudonimy:"
# [8] "Udział w konspiracji 1939-1944:"
# [9] "Oddział:"
# [10] "Szlak bojowy:"
# [11] "Miejsce (okoliczności) śmierci :"
# [12] "Uwagi:"
# [13] "Publikacje :"
然后,您可以找出哪一个是“Rocznik”——在本例中是第五个。在原始答案中(我已对其进行编辑以使其更清晰),我有
btxt2 <- h %>%
html_elements(css=glue("div.biogram--info:nth-child({ind-1})")) %>%
html_text()
首先,机械原理 - glue()
函数类似于 paste()
或 paste0()
,但有时它的作用更清晰一些。在上面的语句中:
glue("div.biogram--info:nth-child({ind-1})")
将等同于以下任何一个:
paste0("div.biogram--info:nth-child(", ind-1, ")")
paste("div.biogram--info:nth-child(", ind-1, ")", sep="")
在 glue()
中,大括号 {}
中出现的任何内容都会在 R 中进行计算,然后将结果放入文本中。从上面的代码 ind
识别出与“Rocznik”相关联的值 <div>
,但是当我们查看 div.biogram--info
的孩子时,我们看到一些 children 有多个条目。这是第四个 child ind-1
拥有“Rocznik”条目。
h %>%
html_elements(css="div.biogram--info:nth-child(1)") %>%
html_text()
# [1] "\n Pseudonim:\n \"Lena\"\n "
# [2] "\n Data urodzenia:\n -\n "
# [3] "\n Data śmierci:\n -\n "
h %>%
html_elements(css="div.biogram--info:nth-child(2)") %>%
html_text()
# character(0)
h %>%
html_elements(css="div.biogram--info:nth-child(3)") %>%
html_text()
# [1] "\n Funkcja:\n -\n "
h %>%
html_elements(css="div.biogram--info:nth-child(4)") %>%
html_text()
# [1] "\n Rocznik:\n 1901\n "
然后代码只提取它找到的任何连续数字。我已经将上面的答案编辑为可能更可靠的答案。如果你回头看看 html 来源的图片,你会看到对于每个 "biogram--info"
div,都有一个 "tag"
class div 保存标题和 "info"
class div 保存与该标题关联的值。使用以下代码,您可以检索与每个 "tag"
条目相对应的所有 "info"
条目:
btxt2 <- h %>%
html_elements(css=glue("div.biogram--info div.info")) %>%
html_text()
btxt2
# [1] "\"Lena\""
# [2] "-"
# [3] "-"
# [4] "-"
# [5] "1901"
# [6] "starszy strzelec"
# [7] "\"Lenarska\", \"Lena\""
# [8] "Narodowe Siły Zbrojne - Okręg I A Warszawa-Miasto"
# [9] "Armia Krajowa - Grupa \"Północ\" - zgrupowanie \"Sienkiewicz\" - następnie odcinek bojowy \"Kuba\" - \"Sosna\" - kompania P-20, następnie w 1. batalionie szturmowym KB \"Nałęcz\" . W Śródmieściu w batalionie KB \"Sokół\" - patrol sanitarny."
# [10] "Stare Miasto - kanały - Śródmieście Północ"
# [11] " Poległa na ul. Kopernika (VIII-IX 1944). Inne wersja - zmarła 1992-10-10\n"
# [12] "Inny spotykany przydział - Narodowe Siły Zbrojne - Grupa \"Topór\""
# [13] "Wielka Ilustrowana Encyklopedia Powstania Warszawskiego Suplement, Warszawa, 2009"
要获取与“Rocznik”关联的值,您可以采用 btxt2
的 ind
条目,就像现在在上面的答案中所做的那样。
亲爱的集体智慧
我正在努力尝试使用 rvest 从 https://www.1944.pl/powstancze-biogramy,ord,nazwisko,0,strona,1.html
中解析 table我需要遍历 table 的所有节点并一一提取其值。然后迭代到下一页并重复。
我打算单独读取 table 值,因为我需要在代码中添加一个变体循环 - 对于每一行,如果“Data urodzenia”列中的值等于“-”,则程序应输入与该行对应的网页并提取其他值(标记为“Rocznik”)。
目前,我无法强制 rvest 从 table 中读取值。我想我不太遵循 html 选择器的想法...我可以使用以下函数中的 (".museumTableRow") 标签阅读整个 table (每页) :
library(rvest)
library(tidyverse)
page <- read_html("https://www.1944.pl/powstancze-biogramy,ord,nazwisko,0,strona,1.html")
getPage <- function(html){
html %>%
html_nodes(".museumTableRow") %>%
html_text() %>%
str_trim() %>%
unlist()
}
Append_page <- getPage(page)
...但是当我尝试对 table 的特定单元格使用选择器时,我得到一个空的(“字符(0)”)响应。我试图通过手动检查页面并按照库创建者的建议使用 selectorgadget 插件来查找相关标签。这些看起来很奇怪(对我来说),例如。对于“Nazwisko”列中的名字,selectorgadget 建议:
".footable-even:nth-child(1) .footable-第一列.museumTableRow"
所以我也试着和他们一起玩,但我没有成功。我想我不完全理解它是如何工作的。对于如何强制 rvest 逐个单元格读取此 table 并将后续单元格中的值附加到 data.table.
的任何建议,我将不胜感激我希望这足够具体。
这应该有效:
library(glue)
page <- read_html("https://www.1944.pl/powstancze-biogramy,ord,nazwisko,0,strona,1.html")
dat <- page %>% html_elements(css="tbody tr")
txt <- dat %>% html_text()
hrefs <- dat %>% html_element("a") %>% html_attr("href")
s <- lapply(1:length(txt), function(i)trimws(strsplit(txt[i], split="\n")[[1]]))
out_txt <- t(sapply(s, function(x)x[which(x != "")]))
stem <- "https://www.1944.pl"
for(i in 1:nrow(out_txt)){
if(out_txt[i,6] == "-"){
u <- paste0(stem, hrefs[i])
h <- read_html(u)
btxt <- h %>% html_elements(css="div.biogram--info div.tag") %>% html_text()
ind <- grep("Rocznik", btxt)
if(length(ind) > 0){
btxt2 <- h %>% html_elements(css=glue("div.biogram--info div.info")) %>% html_text()
out_txt[i,6] <- btxt2[ind]
}else{
out_txt[i,6] <- NA_character_
}
}
}
head(out_txt)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7]
# [1,] "Abajew" "Aleksander" "-" "-" "-" "1916-06-06" "-"
# [2,] "Abakanowicz" "Piotr" "-" "-" "\"Grey\"" "1890-06-21" "1948-06-01"
# [3,] "Abakanowicz" "Maria" "-" "-" "\"Lena\"" "1901" "-"
# [4,] "Abczyńska" "Alicja" "Henryka" "sanitariuszka" "\"Ciocia Stasia\"" "1900-02-09" "1989-04-26"
# [5,] "Abczyńska" "Janina" "-" "pielęgniarka" "\"Julia\"" "1883-06-15" "1944-08-30"
# [6,] "Abczyński" "Stanisław" "-" "-" "\"Stefan\"" NA "-"
在上面的代码中,它获取了行中第一个 <a>
标签的数据和 href。如果第 i 行的第 6 列是 "-"
,它就会转到该引用。如果有一个标记为 "Rocznik"
的条目,如果存在则获取年份,否则用缺失值替换该条目。
编辑:关于 CSS 选择器的详细信息
我假设 stem <- "https://www.1944.pl"
部分之前的所有内容都非常简单,因为它或多或少都遵循您已经走的路。那么,让我们深入研究 for
循环以及它们是如何工作的。正如您所指出的,最初第三行在第六列中有一个 "-"
作为其条目,这应该会触发另一次查找。所以,这意味着应该遵循第三个 href:
hrefs[3]
# [1] "/powstancze-biogramy/maria-abakanowicz,845.html"
为此,我们可以将其粘贴到之前定义的 stem
上以生成有效的 URL,我们将其读入 h
。如果您在浏览器中访问 URL,您会看到:
您希望能够识别与“Rocznik”关联的号码。如果您 right-click 选择“Rocznik”一词并选择“检查”,您将看到:
您会注意到所有条目都在 <div>
和 class "biogram--info"
中。此外,每个条目的标题都在 <div>
和 class "tag"
中。我编辑了上面的答案,通过使用 "tag"
div 使结果更清晰一些。 btxt
的结果如下所示:
btxt <- h %>%
html_elements(css="div.biogram--info div.tag") %>%
html_text()
btxt
# [1] "Pseudonim:"
# [2] "Data urodzenia:"
# [3] "Data śmierci:"
# [4] "Funkcja:"
# [5] "Rocznik:"
# [6] "Stopień:"
# [7] "Pseudonimy:"
# [8] "Udział w konspiracji 1939-1944:"
# [9] "Oddział:"
# [10] "Szlak bojowy:"
# [11] "Miejsce (okoliczności) śmierci :"
# [12] "Uwagi:"
# [13] "Publikacje :"
然后,您可以找出哪一个是“Rocznik”——在本例中是第五个。在原始答案中(我已对其进行编辑以使其更清晰),我有
btxt2 <- h %>%
html_elements(css=glue("div.biogram--info:nth-child({ind-1})")) %>%
html_text()
首先,机械原理 - glue()
函数类似于 paste()
或 paste0()
,但有时它的作用更清晰一些。在上面的语句中:
glue("div.biogram--info:nth-child({ind-1})")
将等同于以下任何一个:
paste0("div.biogram--info:nth-child(", ind-1, ")")
paste("div.biogram--info:nth-child(", ind-1, ")", sep="")
在 glue()
中,大括号 {}
中出现的任何内容都会在 R 中进行计算,然后将结果放入文本中。从上面的代码 ind
识别出与“Rocznik”相关联的值 <div>
,但是当我们查看 div.biogram--info
的孩子时,我们看到一些 children 有多个条目。这是第四个 child ind-1
拥有“Rocznik”条目。
h %>%
html_elements(css="div.biogram--info:nth-child(1)") %>%
html_text()
# [1] "\n Pseudonim:\n \"Lena\"\n "
# [2] "\n Data urodzenia:\n -\n "
# [3] "\n Data śmierci:\n -\n "
h %>%
html_elements(css="div.biogram--info:nth-child(2)") %>%
html_text()
# character(0)
h %>%
html_elements(css="div.biogram--info:nth-child(3)") %>%
html_text()
# [1] "\n Funkcja:\n -\n "
h %>%
html_elements(css="div.biogram--info:nth-child(4)") %>%
html_text()
# [1] "\n Rocznik:\n 1901\n "
然后代码只提取它找到的任何连续数字。我已经将上面的答案编辑为可能更可靠的答案。如果你回头看看 html 来源的图片,你会看到对于每个 "biogram--info"
div,都有一个 "tag"
class div 保存标题和 "info"
class div 保存与该标题关联的值。使用以下代码,您可以检索与每个 "tag"
条目相对应的所有 "info"
条目:
btxt2 <- h %>%
html_elements(css=glue("div.biogram--info div.info")) %>%
html_text()
btxt2
# [1] "\"Lena\""
# [2] "-"
# [3] "-"
# [4] "-"
# [5] "1901"
# [6] "starszy strzelec"
# [7] "\"Lenarska\", \"Lena\""
# [8] "Narodowe Siły Zbrojne - Okręg I A Warszawa-Miasto"
# [9] "Armia Krajowa - Grupa \"Północ\" - zgrupowanie \"Sienkiewicz\" - następnie odcinek bojowy \"Kuba\" - \"Sosna\" - kompania P-20, następnie w 1. batalionie szturmowym KB \"Nałęcz\" . W Śródmieściu w batalionie KB \"Sokół\" - patrol sanitarny."
# [10] "Stare Miasto - kanały - Śródmieście Północ"
# [11] " Poległa na ul. Kopernika (VIII-IX 1944). Inne wersja - zmarła 1992-10-10\n"
# [12] "Inny spotykany przydział - Narodowe Siły Zbrojne - Grupa \"Topór\""
# [13] "Wielka Ilustrowana Encyklopedia Powstania Warszawskiego Suplement, Warszawa, 2009"
要获取与“Rocznik”关联的值,您可以采用 btxt2
的 ind
条目,就像现在在上面的答案中所做的那样。