R中的制表程序包:如何在特定标题后抓取表格

Jac*_*ski 4 r pdf-scraping web-scraping tidyverse

如何从PDF中抓取一些标题文本开头的表格?我正在尝试制表程序包。这是从特定页面获取表格的示例(波兰语“公共卫生需求图”)

library(tabulizer)
library(tidyverse)
options(java.parameters = "-Xmx8000m")

location<-"http://www.mpz.mz.gov.pl/wp-content/uploads/sites/4/2019/01/mpz_choroby_ukladu_kostno_miesniowego_woj_dolnoslaskie.pdf"

(out<-extract_tables(location, pages = 8,encoding = "UTF-8", method = "stream", outdir = getwd())[[4]] %>%
as.tibble())
Run Code Online (Sandbox Code Playgroud)

这使我在特定页面上有一张桌子。但我将从网站上刮取许多此类pdf文件:http : //www.mpz.mz.gov.pl/mapy-dla-30-grup-chorob-2018/,然后是带有每种疾病的许多链接的子页面,获取与波兰每个省的rvest的链接,我需要在特定标题字符串之后抓取表格,例如。

表1.2.2:Struktura zapadalnosci rejestrowanej w zale?no?ci od p?ci,miejsca zamieszkania oraz grupy wiekowej-Choroby uk?adowe tkanki ?? cznej“

我需要检测Tabela(...)Struktura zapadalnosci(...)“,因为表格可能不在同一页面上。非常感谢您事先提供的任何指导和意见。

编辑:我问了一个问题后,到目前为止,我成功地找到了表格可能所在的页面,也许效果很差:

library(pdfsearch)

pages <-
  keyword_search(
    location,
    keyword = c(
      'Tabela',
      'Struktura zapadalnosci rejestrowanej'
    ),
    path = TRUE,
    surround_lines = FALSE
  ) %>%
  group_by(page_num) %>%
  mutate(keyword = paste0(keyword, collapse = ";")) %>%
  filter(
    str_detect(keyword, "Tabela") &
      str_detect(keyword, "Struktura zapadalnosci rejestrowanej")
  ) %>%
  pull(page_num) %>%
  unique()
Run Code Online (Sandbox Code Playgroud)

JBG*_*ber 5

我可以为您解决基本问题,但是有一个问题(请参阅最后)。我用pdftools代替,pdfsearch但在这种情况下它基本上是相同的(用表格查找页面)。为了节省时间,我一开始只下载一次PDF:

options(java.parameters = "-Xmx8000m")# needs to be set before loading tabulizer
library(tabulizer)
library(tidyverse)

location <- "http://www.mpz.mz.gov.pl/wp-content/uploads/sites/4/2019/01/mpz_choroby_ukladu_kostno_miesniowego_woj_dolnoslaskie.pdf"
download.file(location, "test.pdf", mode = "wb")
Run Code Online (Sandbox Code Playgroud)

现在,将pdf转换为data.frame,并在df的一行中插入每一行:

raw <- pdftools::pdf_data("test.pdf") 
pages <- lapply(seq_along(raw), function(p) {
  if (nrow(raw[[p]]) > 0) {
    raw[[p]]$page <- p
    raw[[p]]
  }
}) %>% 
  bind_rows() %>% 
  group_by(y, page) %>% 
  summarise(text = paste(text, collapse = " ")) %>% 
  arrange(page, y)
Run Code Online (Sandbox Code Playgroud)

此data.frame是可搜索的,我们仅保留适合您关键字的行:

tables <- pages %>% 
  filter(grepl("Tabela .* Struktura zapadalnosci", text))
Run Code Online (Sandbox Code Playgroud)

有8行适合该关键字。我们仅从中提取表。此外,lapply循环内的函数仅使矩阵具有最多的行。如果一页上有两个表可能是个问题,但是通常只使用能够tabulizer找到表结构的“最佳猜测”就可以了。

tables_list <- lapply(tables$page, function(p) {
  cat(p, "\n")
  out <- extract_tables("test.pdf", 
                        pages = p,
                        encoding = "UTF-8", 
                        method = "stream", 
                        output = "matrix")
  out <- as_tibble(out[[which.max(sapply(out, nrow) + sapply(out, ncol))]]) # keep the biggest table
  attr(out, "caption") <- tables$text[tables$page %in% p]
  return(out)
})
Run Code Online (Sandbox Code Playgroud)

tables_list现在,该对象包含的列表data.frames,每个都有一个转换后的表:

> tables_list[[1]]
# A tibble: 16 x 8
   V1                  V2    V3    V4    V5    V6    V7    V8   
   <chr>               <chr> <chr> <chr> <chr> <chr> <chr> <chr>
 1 dolno?l?skie        77,05 74,65 4,04  10,59 13,37 27,87 44,14
 2 kujawsko-pomorskie  78,12 65,93 4,29  14,96 14,82 27,01 38,92
 3 lubelskie           76,50 56,83 2,67  14,83 17,00 29,00 36,50
 4 lubuskie            79,10 76,23 4,92  12,70 12,70 30,74 38,93
 5 ?ódzkie             74,37 67,77 6,45  13,84 15,09 30,03 34,59
 6 ma?opolskie         72,71 55,35 6,99  14,63 12,01 25,87 40,50
 7 mazowieckie         76,31 68,52 5,89  12,11 12,30 27,03 42,67
 8 opolskie            79,55 54,65 4,83  10,04 17,47 26,02 41,64
 9 podkarpackie        75,10 47,32 7,57  14,86 18,29 25,31 33,98
10 podlaskie           74,18 68,00 5,82  10,55 17,09 32,36 34,18
11 pomorskie           76,57 74,96 5,71  12,74 13,76 26,65 41,14
12 ?l?skie             73,51 81,15 4,89  14,96 14,43 26,64 39,08
13 ?wi?tokrzyskie      74,45 56,51 4,91  14,00 14,74 27,27 39,07
14 warmi?sko-mazurskie 75,91 63,22 5,62  13,59 18,48 29,53 32,79
15 wielkopolskie       72,66 62,71 3,62  14,37 14,77 29,45 37,79
16 zachodniopomorskie  74,26 73,21 8,44  13,71 11,60 24,89 41,35
Run Code Online (Sandbox Code Playgroud)

我还将每个表的(的第一行)标题作为属性添加到data.frame

> attr(tables_list[[1]], "caption")
[1] "Tabela 1.2.2: Struktura zapadalnosci rejestrowanej w zale?no?ci od p?ci, miejsca zamieszkania oraz grupy"
Run Code Online (Sandbox Code Playgroud)

将此与pdf进行比较:

在此处输入图片说明

看起来这很好用,只是列名不见了。不知道是否有保留方式,但是您的问题中未包含该方式,因此也许您已经有了解决方案?