,html,r"/>

首页 > 解决方案 > R从网络中提取表格,没有

问题描述

我试图取消本周末举行的波兰选举的结果,但我遇到了一个问题,即在添加每个整数随机浮点数之前。

我尝试过使用htmltab,但它不起作用 - 正如您所看到的那样添加了随机数

library(htmltab)
url <- "https://wybory2018.pkw.gov.pl/pl/geografia/020000#results_vote_council"
tmp <- htmltab::htmltab(doc = html, which = 1) 
tmp

  Wyszczególnienie              Liczba
2      Mieszkańców 0.972440432 755 957
3         Wyborców 0.977263472 273 653
4          Obwodów      0.99998061 940

我已经检查了 html 有什么问题:

library(xml2)
library(rvest)
webpage <- xml2::read_html(url)
a <- webpage %>%
  rvest::html_nodes("tbody") 

a[1]

<tbody>\n<tr>\n<td>Mieszkańców</td>\n                            <td class=\"table-number\">\n<span class=\"hidden\">0.97244043</span>2 755 957</td>\n                        </tr>\n<tr>\n<td>Wyborców</td>\n                            <td class=\"table-number\">\n<span class=\"hidden\">0.97726347</span>2 273 653</td>\n                        </tr>\n<tr>\n<td>Obwodów</td>\n                            <td class=\"table-number\">\n<span class=\"hidden\">0.9999806</span>1 940</td>\n                        </tr>\n</tbody>"

我认为问题在于<span class=\"hidden\">,但如何摆脱它?

编辑

我需要来自第 9 表的信息以及各方的结果

Nr listy  Komitet wyborczy  Liczba  % głosów ważnych
Głosów na kandydatów komitetu Kandydatów    
12  KOMITET WYBORCZY WYBORCÓW Z DUTKIEWICZEM DLA DOLNEGO ŚLĄSKA 93 260  45  8.29% 
9 KOMITET WYBORCZY WYBORCÓW WOLNOŚĆ W SAMORZĄDZIE 15 499  46  1.38% 
8 KOMITET WYBORCZY WYBORCÓW KUKIZ'15  53 800  41  4.78% 
1 KOMITET WYBORCZY WYBORCÓW BEZPARTYJNI SAMORZĄDOWCY  168 442 46  14.98%  
11  KOMITET WYBORCZY WOLNI I SOLIDARNI  9 624 38  0.86% 
7 KOMITET WYBORCZY RUCH NARODOWY RP 14 874  38  1.32% 
10  KOMITET WYBORCZY PRAWO I SPRAWIEDLIWOŚĆ 320 908 45  28.53%  
2 KOMITET WYBORCZY POLSKIE STRONNICTWO LUDOWE 58 820  46  5.23% 
6 KOMITET WYBORCZY PARTII RAZEM 18 087  44  1.61% 
3 KOMITET WYBORCZY PARTIA ZIELONI 19 783  36  1.76% 
5 KOALICYJNY KOMITET WYBORCZY SLD LEWICA RAZEM  61 889  46  5.50% 
4 KOALICYJNY KOMITET WYBORCZY PLATFORMA.NOWOCZESNA KOALICJA OBYWATELSKA 289 831 46  25.77%  

编辑 2

我发现不是最优雅的解决方案:

#https://stackoverflow.com/questions/7963898/extracting-the-last-n-characters-from-a-string-in-r
substrRight <- function(x, n){
  substr(x, nchar(x)-n+1, nchar(x))
}

tmp <- htmltab::htmltab(doc = html, which = 9) 

tmp2 <- xml2::read_html(html) %>%
  rvest::html_nodes("tbody") %>%
  magrittr::extract2(9)  %>%
  rvest::html_nodes("tr") %>%
  rvest::html_nodes("td") %>%
  rvest::html_nodes("span") %>%
  rvest::html_text() %>%
  matrix(ncol = 4, byrow = T) %>%
  data.frame() 

names(tmp) <- c("a", "b", "c", "d", "e", "f", "g")
tmp3 <- cbind(tmp, tmp2) %>%
  mutate(n_to_delate = nchar(X1),
         c1 = as.character(c),
         n_whole = nchar(c1),
         c2 = substrRight(c1, n_whole - n_to_delate),
         c3 = gsub(" ", "", c2),
         c4 = as.numeric(c3)) %>%
  select(b, c4)

names(tmp3) <- c("party", "n_of_votes")

标签: htmlr

解决方案


解决原来的问题:

您可以在转换为表之前删除这些节点:

library(rvest)

pg <- read_html("https://wybory2018.pkw.gov.pl/pl/geografia/020000#results_vote_council")

tbl_1 <- html_nodes(pg, xpath=".//table[@class = 'stat_table']")[1]

xml_remove(html_nodes(tbl_1, xpath=".//span[@class='hidden']"))

html_table(tbl_1)
## [[1]]
##   Wyszczególnienie    Liczba
## 1      Mieszkańców 2 755 957
## 2         Wyborców 2 273 653
## 3          Obwodów     1 940

解决更新的要求:

library(rvest)

pg <- read_html("https://wybory2018.pkw.gov.pl/pl/geografia/020000#results_vote_council")

让我们针对那个特定的表。使用文档的“查看源代码”版本,我们可以找到该表之前的标题,然后到达该表:

target_tbl <- html_node(pg, xpath=".//header[contains(., 'mandatów pomiędzy')]/following-sibling::table")

仍然摆脱隐藏的跨度:

xml_remove(html_nodes(target_tbl, xpath=".//span[@class='hidden']"))

现在,我们需要知道有多少真正的列,因为它有一个多行的愚蠢标题之一,其中<td>'s 跨越多个列:

length(
  html_nodes(target_tbl, xpath=".//tbody/tr[1]") %>% 
    html_nodes("td")
) -> n_cols

现在我们拉出每一列,设置好列名,将其转换为数据框并删除刚刚填充填充条的垃圾列:

as.data.frame(
  setNames(
    lapply(1:n_cols, function(.idx) {
      html_nodes(target_tbl, xpath=sprintf(".//tbody/tr/td[%s]", .idx)) %>% 
        html_text(trim=TRUE)
    }),
    c(
      "nr_listy", "komitet_wyborczy", "głosów_na_kandydatów_komitetu", 
      "kandydatów", "mandatów", "pct_głosów_ważnych", "junk", 
      "udział_w_podziale_mandatów"
    )
  ),
  stringsAsFactors = FALSE
) -> xdf

xdf$junk <- NULL

str(xdf)
## 'data.frame': 12 obs. of  7 variables:
##  $ nr_listy                     : chr  "1" "2" "3" "4" ...
##  $ komitet_wyborczy             : chr  "KOMITET WYBORCZY WYBORCÓW BEZPARTYJNI SAMORZĄDOWCY" "KOMITET WYBORCZY POLSKIE STRONNICTWO LUDOWE" "KOMITET WYBORCZY PARTIA ZIELONI" "KOALICYJNY KOMITET WYBORCZY PLATFORMA.NOWOCZESNA KOALICJA OBYWATELSKA" ...
##  $ głosów_na_kandydatów_komitetu: chr  "168 442" "58 820" "19 783" "289 831" ...
##  $ kandydatów                   : chr  "46" "46" "36" "46" ...
##  $ mandatów                     : chr  "6" "1" "0" "13" ...
##  $ pct_głosów_ważnych           : chr  "14.98%" "5.23%" "1.76%" "25.77%" ...
##  $ udział_w_podziale_mandatów   : chr  "Tak" "Tak" "Nie" "Tak" ...

我认为管道不会使lapply()块更具可读性,但以防万一:

lapply(1:n_cols, function(.idx) {
  html_nodes(target_tbl, xpath=sprintf(".//tbody/tr/td[%s]", .idx)) %>% 
    html_text(trim=TRUE)
}) %>% 
  setNames(c(
    "nr_listy", "komitet_wyborczy", "głosów_na_kandydatów_komitetu", 
    "kandydatów", "mandatów", "pct_głosów_ważnych", "junk", 
    "udział_w_podziale_mandatów"
  )) %>% 
  as.data.frame(stringsAsFactors = FALSE) -> xdf

推荐阅读