6

如何从PDF中刮取带有一些标题文本的表格?我正在尝试使用 tabulizer 包。这是从特定页面获取表格的示例(波兰语“公共卫生需求地图”)

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())

这让我在特定页面获得一张桌子。但是我会从网站上刮掉很多这样的 pdf:http : //www.mpz.mz.gov.pl/mapy-dla-30-grup-chorob-2018/,然后是每个疾病都有很多链接的子页面,获取与 rvest 的链接,对于波兰的每个省,我需要在特定的标题字符串之后抓取表格,例如。

Tabela 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()
4

2 回答 2

6

我可以帮助您解决基本问题,但有一个问题(见最后)。我使用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")

现在将 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)

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

tables <- pages %>% 
  filter(grepl("Tabela .* Struktura zapadalnosci", text))

有 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)
})

该对象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

我还将每个表的(第一行)标题作为属性添加到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"

将此与pdf进行比较:

在此处输入图像描述

似乎这很好用,只是列名不见了。不确定是否有办法保留它们,但你的问题中没有包含,所以也许你已经有了解决方案?

于 2019-04-03T16:52:11.387 回答
0

您应该尝试Rcrawler

它的主要Rcrawler功能似乎是专门为您的需要而设计的 - 带有它的KeywordsFilter论点:

KeywordsFilter  

字符向量,适用于只希望抓取或收集包含一个或多个关键字的网页的用户。Rcrawler 根据创建的关键字的数量计算准确度分数。此参数必须是一个向量,其中至少包含一个关键字,例如 c("mykeyword")。

于 2019-04-03T15:26:43.627 回答