R中的Tabulizer包:如何在特定标题后刮取表格

问题描述 投票:4回答:2

如何从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的链接,对于波兰的每个省份,我需要在特定的标题字符串之后刮取表格,例如。

表1.2.2:可记录的成熟结构取决于性别,居住地和年龄组 - 系统性结缔组织病“

我需要检测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()
r web-scraping tidyverse pdf-scraping
2个回答
4
投票

我可以帮助你解决你的基本问题,但有一个问题(见最后)。我使用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进行比较:

enter image description here

看起来这很好用,除了列名已经消失了。不确定是否有办法保留它们,但这不包括在你的问题中,所以也许你已经有了解决方案?


0
投票

你应该尝试Rcrawler

其主要的Rcrawler功能似乎是专门为您的需求而设计的 - 其KeywordsFilter参数:

KeywordsFilter  

字符向量,对于希望仅收集或收集包含一个或多个关键字的网页的用户。 Rcrawler根据已建立关键字的数量计算准确度分数。此参数必须是包含至少一个关键字(如c(“mykeyword”))的向量。

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