我是 R 的新手,在用 R 創建一個好的網路爬蟲時遇到了一些麻煩......自從我開始學習這門語言以來只有 5 天。所以,任何幫助我都會感激!
主意
我正在嘗試在 Wikipedia 上從 2003 年到 2021 年在網上抓取“Campeonato Brasileiro”的分類表,以便稍后將團隊分組以分析一些東西。
解釋和問題
我正在刮掉 2002 年錦標賽的頁面。我閱讀了 HTML 頁面以提取我在 Google Chrome 上使用“SelectorGadget”擴展程式選擇的 HTML 節點。有一些考慮:
- 我試圖訪問的頁面來自 2002 年錦標賽。我這樣做是因為更容易提取出現在頁面最后的板上的表格的鏈接,只為所有 (tr:nth-child(9) div a) 選擇一個選擇器來訪問它們的鏈接HTML 屬性“href”;
- 選擇的 CSS 來自 2003 年的冠軍頁面。
所以,在我扭曲的頭腦中,我想:“嘿!我要創建一個函式來從這些頁面中提取表格,并將它們保存在資料框中!”。但是,它出錯了,我不明白為什么......當我嘗試運行“tabelageral”行時,回傳以下錯誤:“UseMethod 錯誤(“xml_find_all”):沒有適用于 'xml_find_all' 的方法應用于“字符”類的物件。我認為它正在讀取字串而不是 xml。我在這里有什么誤解?我的錯誤在哪里?“應用”方法?從現在開始,謝謝!
代碼
library("dplyr")
library("rvest")
link_wikipedia <- "https://pt.wikipedia.org/wiki/Campeonato_Brasileiro_de_Futebol_de_2002"
pagina_wikipedia <- read_html(link_wikipedia)
links_temporadas <- pagina_wikipedia %>%
html_nodes("tr:nth-child(9) div a") %>%
html_attr("href") %>%
paste("https://pt.wikipedia.org", ., sep = "")
tabela <- function(link){
pagina_tabela <- read_html(link)
tabela_wiki = link %>%
html_nodes("table.wikitable") %>%
html_table() %>%
paste(collapse = "|")
}
tabela_geral <- sapply(links_temporadas, FUN = tabela, USE.NAMES = FALSE)
tabela_final <- data.frame(tabela_geral)
uj5u.com熱心網友回復:
您可以通過執行以下操作從這些鏈接中獲取所有表格:
tabela <- function(link){
read_html(link) %>% html_nodes("table.wikitable") %>% html_table()
}
all_tables = lapply(links_temporadas, tabela)
names(all_tables)<-2003:2022
這為您提供了一個長度為 20 的串列,命名2003為2022(即每一年的一個元素)。每個元素本身就是一個表格串列(即在該鏈接上links_temporadas可用的表格。請注意,每個鏈接上可用的表格數量各不相同。
lengths(all_tables)
2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022
6 5 10 9 10 12 11 10 12 11 13 14 17 16 16 16 16 15 17 7
您將需要確定您每年對哪些表格感興趣。
uj5u.com熱心網友回復:
這是一種方法。它比你的函式更復雜,因為這些頁面有多個表,所以函式只回傳列名匹配的表"Pos."。
然后,在rbinding 表之前,只保留公共列,因為舊表少了一列, column "M"。
suppressPackageStartupMessages({
library("dplyr")
library("rvest")
})
link_wikipedia <- "https://pt.wikipedia.org/wiki/Campeonato_Brasileiro_de_Futebol_de_2002"
pagina_wikipedia <- read_html(link_wikipedia)
links_temporadas <- pagina_wikipedia %>%
html_nodes("tr:nth-child(9) div a") %>%
html_attr("href") %>%
paste("https://pt.wikipedia.org", ., sep = "")
tabela <- function(link){
pagina_tabela <- read_html(link)
lista_wiki <- pagina_tabela %>%
html_elements("table.wikitable") %>%
html_table()
i <- sapply(lista_wiki, \(x) "Pos." %in% names(x))
i <- which(i)[1]
lista_wiki[[i]]
}
tabela_geral <- sapply(links_temporadas, FUN = tabela, USE.NAMES = FALSE)
sapply(tabela_geral, ncol)
#> [1] 12 12 12 12 12 12 13 13 13 13 13 13 13 13 13 13 13 13 13 13
#sapply(tabela_geral, names)
common_names <- Reduce(intersect, lapply(tabela_geral, names))
tabela_reduzida <- lapply(tabela_geral, `[`, common_names)
tabela_final <- do.call(rbind, tabela_reduzida)
head(tabela_final)
#> # A tibble: 6 x 12
#> Pos. Equipes P J V E D GP GC SG `%`
#> <int> <chr> <chr> <int> <int> <int> <int> <int> <int> <chr> <int>
#> 1 1 Cruzeiro 100 46 31 7 8 102 47 55 72
#> 2 2 Santos 87 46 25 12 9 93 60 33 63
#> 3 3 S?o Paulo 78 46 22 12 12 81 67 14 56
#> 4 4 S?o Caetano 742 46 19 14 13 53 37 16 53
#> 5 5 Coritiba 73 46 21 10 15 67 58 9 52
#> 6 6 Internacional 721 46 20 10 16 59 57 2 52
#> # ... with 1 more variable: `Classifica??o ou rebaixamento` <chr>
由reprex 包于 2022-04-03 創建(v2.0.1)
要擁有所有列,包括"M"列:
data.table::rbindlist(tabela_geral, fill = TRUE)
uj5u.com熱心網友回復:
您可以使用:contains按類定位適當的表,然后使用該表包含的子字串。此外,您可以使用html_table()從匹配節點中提取表格格式。然后,您可以對所需列的向量進行子集化。我不知道正確的足球術語,所以已經猜到要子集的列。您可以調整columns矢量。
如果您包裝年份和構造的 url 以在map2_dfr()呼叫內部發出請求,您可以回傳所有所需年份的單個DataFrame。
library(tidyverse)
library(rvest)
years <- 2003:2021
urls <- paste("https://pt.wikipedia.org/wiki/Campeonato_Brasileiro_de_Futebol_de_", years, sep = "")
columns <- c("Pos.", "Equipes", "GP", "GC", "SG")
df <- purrr::map2_dfr(urls, years, ~
read_html(.x, encoding = "utf-8") %>%
html_element('.wikitable:contains("ou rebaixamento")') %>%
html_table() %>%
.[columns] %>%
mutate(year = .y, SG = as.character(SG)))
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/456926.html
上一篇:網路抓取口袋妖怪資料
