使用 rvest 和 tidyverse 的数据抓取问题

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

我是数据抓取的新手,我正在尝试从网页中抓取表格(https://vos.oph.fi/cgi-bin/tiedot2.cgi?saaja=1361;tnimi=kust/v08/k05k7s。利斯)。 我目前正在使用 tidyverse 通过代码来执行此操作(selectorgadget 用于查找正确的节点,尽管我怀疑它是否正常工作):

url <- "https://vos.oph.fi/cgi-bin/tiedot2.cgi?saaja=1361;tnimi=kust/v08/k05k7s.lis"
webpage <- read_html(url)
table_code <- html_nodes(webpage, ".table") 
table1<-html_table(table_code , header=TRUE, trim=TRUE)
table1

但是,最终结果是一个没有任何内容的表(小标题:0x0)

我做错了什么?

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

如果您检查 html 源代码,您应该注意到 txt 报告位于代表预格式化文本的

<pre>
元素中。由于恰好只有一个
pre
元素,您可以安全地使用
"pre"
作为选择器,获取所有文本并用换行符分割它。

我假设您只在主表之后,对于这种预先格式化的文本报告

readr::read_fwf()
(固定宽度文件)可以非常方便。
我们还假设报告开始和行数是固定的,我们可以手动选择一系列行,将其解析为标题和表主体。

library(rvest)
library(readr)
library(tidyr)
library(dplyr)
library(stringr)

url_ <- "https://vos.oph.fi/cgi-bin/tiedot2.cgi?saaja=1361;tnimi=kust/v08/k05k7s.lis"

# read lines from <pre> .. </pre> section
report <- 
  read_html(url_) |> 
  html_element("pre") |> 
  html_text() |> 
  read_lines()

# check relevant part
str_view(report)[18:30]
#> [18] │      VALTIONOSUUSPOHJAAN KUULUVAT MENOT
#> [19] │                                             01            02             03             04             Menot yhteensä *)
#> [20] │                                        Palkkaukset     Muut menot  Arvonlisävero       Alv%            euroa   e/oppilas
#> [21] │  
#> [22] │      010  Opetus                         1.206.307        363.051         14.705        4,1        1.584.063       5.194
#> [23] │      020  Majoitus ja kuljetus                   0              0              0        0,0                0           0
#> [24] │      031  Oppilasruokailu                   54.862         57.595         11.856       20,6          124.313         408
#> [25] │      039  Muu oppilashuolto                 51.455         12.692              0        0,0           64.147         210
#> [26] │      061  Sisäinen hallinto                 27.751         19.188          2.249       11,7           49.188         161
#> [27] │      062  Kiinteistöjen ylläpito            31.447        290.850         25.417        8,7          347.714       1.140
#> [28] │      090  Pienet hankkeet                                       0              0        0,0                0           0
#> [29] │                                      -----------------------------------------------------------------------------------
#> [30] │           Yhteensä                       1.371.822        743.376         54.227        7,3        2.169.425       7.113

# process lines that make up a 2-row header, build valid column names
col_names <- 
  report[19:20] |> 
  I() |> 
  read_fwf(show_col_types = FALSE) |> 
  t() |> 
  `colnames<-`(c("h1", "h2")) |> 
  as_tibble() |> 
  mutate(h1 = str_remove(h1, "\\d+"), 
         h2 = str_replace(h2, "\\s{2,}", "|")) |> 
  separate_longer_delim(h2, "|") |> 
  unite(names, c(h1, h2)) |> 
  pull(names) |> 
  janitor::make_clean_names()
glimpse(col_names)
#>  chr [1:6] "palkkaukset" "muut_menot" "arvonlisavero" "alv_percent" ...

# process report body, configure locale for used grouping and decimal marks,
# set column names
report_tbl <- 
  report[22:28] |> 
  I() |> 
  read_fwf(locale = locale("fi", grouping_mark = ".", decimal_mark = ","), show_col_types = FALSE) |> 
  setNames(c("x1", "x2", col_names)) 

结果小标题:

report_tbl
#> # A tibble: 7 × 8
#>   x1    x2                     palkkaukset muut_menot arvonlisavero alv_percent
#>   <chr> <chr>                        <dbl>      <dbl>         <dbl>       <dbl>
#> 1 010   Opetus                     1206307     363051         14705         4.1
#> 2 020   Majoitus ja kuljetus             0          0             0         0  
#> 3 031   Oppilasruokailu              54862      57595         11856        20.6
#> 4 039   Muu oppilashuolto            51455      12692             0         0  
#> 5 061   Sisäinen hallinto            27751      19188          2249        11.7
#> 6 062   Kiinteistöjen ylläpito       31447     290850         25417         8.7
#> 7 090   Pienet hankkeet                 NA          0             0         0  
#> # ℹ 2 more variables: menot_yhteensa_euroa <dbl>,
#> #   menot_yhteensa_e_oppilas <dbl>
glimpse(report_tbl)
#> Rows: 7
#> Columns: 8
#> $ x1                       <chr> "010", "020", "031", "039", "061", "062", "09…
#> $ x2                       <chr> "Opetus", "Majoitus ja kuljetus", "Oppilasruo…
#> $ palkkaukset              <dbl> 1206307, 0, 54862, 51455, 27751, 31447, NA
#> $ muut_menot               <dbl> 363051, 0, 57595, 12692, 19188, 290850, 0
#> $ arvonlisavero            <dbl> 14705, 0, 11856, 0, 2249, 25417, 0
#> $ alv_percent              <dbl> 4.1, 0.0, 20.6, 0.0, 11.7, 8.7, 0.0
#> $ menot_yhteensa_euroa     <dbl> 1584063, 0, 124313, 64147, 49188, 347714, 0
#> $ menot_yhteensa_e_oppilas <dbl> 5194, 0, 408, 210, 161, 1140, 0

创建于 2024-09-01,使用 reprex v2.1.1

© www.soinside.com 2019 - 2024. All rights reserved.