如何使用 rvest 为 html_element() 选择正确的选择器?

问题描述 投票:0回答:1

我对使用 rvest 抓取一些数据感兴趣,并使用以下教程作为指导:
https://statsandr.com/blog/web-scraping-in-r/
我了解如何在 html 浏览器中找到正确的表格,并已复制该表格,如教程中所示。

library(rvest)
link <- "https://en.wikipedia.org/wiki/List_of_Formula_One_drivers"
page <- read_html(link)

# scrape F1 driver table
drivers_F1 <- html_element(page, "table.sortable") %>%
  html_table()

据我所知,这两个表都有相同的选择器。如何找到正确的选择器来使用 html_element() 在此 wiki 页面上的下表(“按国家/地区列出的一级方程式赛车手列表”)生成表格?

Chrome html source

html_element() 是否默认选择匹配选择器的第一个实例?使用 html_selectors() 时,我可以查看这两个表:

html_elements(page, "table.sortable")
{xml_nodeset (2)}
[1] <table class="wikitable sortable" style="font-size: 85%; text-align:center">\n<caption>Formula One drivers by name\n</caption>\n<tbody>\n<tr> ...
[2] <table class="wikitable sortable" style="text-align:center; text-align:center; font-size:95%">\n<caption>List of Formula One drivers by count ...

此外,如果我使用 html_elements() 函数,我可以通过选择第二个索引元素来生成第二个表。

html_elements(page, "table.sortable")[[2]]%>%
  html_table()

# A tibble: 42 × 7
   Country          Totaldrivers Champions                                Championships         `Race wins` `First driver(s)` Most recent driver(s…¹
   <chr>            <chr>        <chr>                                    <chr>                 <chr>       <chr>             <chr>                 
 1 Argentinadetails 25           1(Fangio [5])                            5(1951, 1954, 1955, … "38\n(Fang… Juan Manuel Fang… Gastón Mazzacane(2001…
 2 Australiadetails 18           2(Brabham [3], Jones)                    4(1959, 1960, 1966, … "43\n(Brab… Tony Gaze(1952 B… Oscar Piastri, Daniel…
 3 Austriadetails   16           2(Rindt, Lauda [3])                      4(1970, 1975, 1977, … "41\n(Rind… Jochen Rindt(196… Christian Klien(2010 …
 4 Belgiumdetails   24           0                                        0                     "11\n(Ickx… Johnny Claes(195… Stoffel Vandoorne(201…
 5 Brazildetails    32           3(Fittipaldi [2], Piquet [3], Senna [3]) 8(1972, 1974, 1981, … "101\n(Fit… Chico Landi(1951… Pietro Fittipaldi(202…
 6 Canadadetails    15           1(J. Villeneuve)                         1(1997)               "17\n(G. V… Peter Ryan(1961 … Lance Stroll(2023 Abu…
 7 Chile            1            0                                        0                     "0"         Eliseo Salazar(1… Eliseo Salazar(1983 B…
 8 China            1            0                                        0                     "0"         Zhou Guanyu(2022… Zhou Guanyu(2023 Abu …
 9 Colombiadetails  3            0                                        0                     "7\n(Monto… Ricardo Londoño(… Juan Pablo Montoya(20…
10 Czech Republic   1            0                                        0                     "0"         Tomáš Enge(2001 … Tomáš Enge(2001 Japan…
# ℹ 32 more rows
# ℹ abbreviated name: ¹​`Most recent driver(s)/Current driver(s)`
# ℹ Use `print(n = ...)` to see more rows

在这种情况下,使用 html_elements() 似乎可以很好地完成工作,但是任何有关 html_element() 为何以这种方式运行的见解都将不胜感激。

html css r web-scraping rvest
1个回答
0
投票

html_elements
返回所有匹配项的列表,而
html_element
返回

与输入长度相同的节点集

即如果有多个匹配,则包含第一个匹配的节点集。

除了使用

html_elements
然后从返回的列表中选择所需的元素之外,您还可以使用
html_element
更具体地获得第二个表,例如使用伪类
:last-of-type
您可以选择最后一个表格,或者使用
:caption
您可以根据文本进行选择,例如表格标题:

library(rvest)
link <- "https://en.wikipedia.org/wiki/List_of_Formula_One_drivers"
page <- read_html(link)

drivers_F1 <- html_element(
  page, 
  "table.sortable:last-of-type"
) |>
  html_table()

head(drivers_F1)
#> # A tibble: 6 × 7
#>   Country     Totaldrivers Champions Championships `Race wins` `First driver(s)`
#>   <chr>       <chr>        <chr>     <chr>         <chr>       <chr>            
#> 1 Argentinad… 25           1(Fangio… 5(1951, 1954… "38\n(Fang… Juan Manuel Fang…
#> 2 Australiad… 18           2(Brabha… 4(1959, 1960… "43\n(Brab… Tony Gaze(1952 B…
#> 3 Austriadet… 16           2(Rindt,… 4(1970, 1975… "41\n(Rind… Jochen Rindt(196…
#> 4 Belgiumdet… 24           0         0             "11\n(Ickx… Johnny Claes(195…
#> 5 Brazildeta… 32           3(Fittip… 8(1972, 1974… "101\n(Fit… Chico Landi(1951…
#> 6 Canadadeta… 15           1(J. Vil… 1(1997)       "17\n(G. V… Peter Ryan(1961 …
#> # ℹ 1 more variable: `Most recent driver(s)/Current driver(s)` <chr>

drivers_F1 <- html_element(
  page,
  "table.sortable:contains('List of Formula One drivers by country')"
) |>
  html_table()

head(drivers_F1)
#> # A tibble: 6 × 7
#>   Country     Totaldrivers Champions Championships `Race wins` `First driver(s)`
#>   <chr>       <chr>        <chr>     <chr>         <chr>       <chr>            
#> 1 Argentinad… 25           1(Fangio… 5(1951, 1954… "38\n(Fang… Juan Manuel Fang…
#> 2 Australiad… 18           2(Brabha… 4(1959, 1960… "43\n(Brab… Tony Gaze(1952 B…
#> 3 Austriadet… 16           2(Rindt,… 4(1970, 1975… "41\n(Rind… Jochen Rindt(196…
#> 4 Belgiumdet… 24           0         0             "11\n(Ickx… Johnny Claes(195…
#> 5 Brazildeta… 32           3(Fittip… 8(1972, 1974… "101\n(Fit… Chico Landi(1951…
#> 6 Canadadeta… 15           1(J. Vil… 1(1997)       "17\n(G. V… Peter Ryan(1961 …
#> # ℹ 1 more variable: `Most recent driver(s)/Current driver(s)` <chr>
© www.soinside.com 2019 - 2024. All rights reserved.