R语言 如何使用pdftools中的pdf_data从多个PDF中选择具有相同字符串的页面?

qc6wkl3g  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(129)

让我们考虑this PDF,在R中导入如下:

library(pdftools)
library(tidyverse)
mylink <- "https://www.probioqual.com/12_PDF/02_EEQ/Modele_Rapport_EEQ.pdf"
mypdf <- pdf_data(mylink)

字符串
pdf_data函数生成一个由35页组成的大列表(每页一个字节,每个字节包括 n 行和6列,其中有 xy 坐标)。
现在让我们考虑一个文件中的许多PDF,使用以下命令导入:

mypdfs_list <- list.files(pattern = '*.pdf')
allpdfs <- lapply(mypdfs_list, pdf_data)


其给出:
x1c 0d1x的数据
allpdfs中,我只想选择那些在右上方框中包含“Limites acceptables”字符串的页面,例如,在PDF的第5页中以黄色突出显示:



注意:选择这个特定的字符串是我发现只选择包含感兴趣的表格的页面的方法。(其中的数量可能会有所不同,从一个pdf到另一个)不感兴趣,所以我想丢弃他们;例如,在上面的PDF中,我想丢弃前4页的文本(但在另一个PDF中,前3页或前5页必须删除,例如)。
使用pdftools::pdf_data,“Limites acceptables”字符串始终位于坐标x>360 & x<580 & y>26 & y<35的区域内。

问题:是否可以使用函数(maplapply或其他,包括例如filter或其他)从导入的pdf中的所有列表中仅选择这些页面(从而丢弃第一个文本页面)?

当然,开放给任何其他方法!
谢谢

wnavrhmk

wnavrhmk1#

您的编程方法是合理的,但由于源代码构造的性质,需要稍微调整,如图所示。
x1c 0d1x的数据
Rtools基于poppler pdftotext。
因此,首先我们需要看看通过将区域调整为常数,PDFtoText可能会提取什么,但由于字符间距和单词分隔符(如上所示),结果可能并不总是如预期的那样。因此,我将感兴趣区域减少到只有两个部分字母字符串。

pdftotext -nopgbrk -enc UTF-8 -layout -fixed 3.8 -f 5 -l 5 -x 365 -W 52 -y 26 -H 11 "Modele_Rapport_EEQ.pdf" -

字符串
结果
Limi tesaccep
现在我们可以把它放在一个循环中并测试所有35个页面。

x 1c 2d 1x
在这个阶段,我们可以看到更多的变化,但是第5-30页是我们想要找到的,并且都有字符串"Limi",所以这是我们的Find过滤器。
因此,使用操作系统的shell可执行文件,我们可以将页面列表过滤到控制台或文件中(或将first和last设置为范围变量)。
然而,这是我不使用Python写更多的地方,这是一个方法(算法),我将如何在本机Windows命令控制台中处理这样的任务。
一旦你有了目标页面的列表,就可以很容易地添加一个二级进程(甚至直接添加),并将结果作为变量,比如在这些页面上重新运行一组不同的命令。

cxfofazt

cxfofazt2#

一个稍微复杂的解决方案,但它的工作原理:

# import all pdfs from the file
mypdfs_list <- list.files(pattern = '*.pdf')
allpdfs <- lapply(mypdfs_list, pdf_data)

# map nested lists to mutate 'page_ok' = 1 when fixed areas contain specific texts
allpdfs  <- map(allpdfs, ~ .x %>%
                   map(~ mutate(., page_ok = case_when(.$x>360 & .$x<580 & .$y>26 & .$y<35 &
                                                       (.$text=="Li" | .$text=="mi") ~ 1, TRUE ~ 0))))
                       
# map nested lists to fill 'page_ok' with 1 if this variable contains at least one value 1
allpdfs  <- map(allpdfs , ~ .x %>%
                   map(~ mutate(., page_ok = if_else(any(.$page_ok == 1), 1, 0))))

# map nested lists to keep only sublists (i.e., tibbles that correspond to pages) for which the sum of 'page_ok' is not 0
allpdfs  <- map(allpdfs , ~ .x %>%
                   keep(~ sum(.$page_ok) != 0))

字符串
第一个不感兴趣的文本页面因此被删除。下面与上面的RStudio截图进行比较:第一个pdf现在有26页而不是29页,第二个pdf 35页而不是38页,第三个pdf 26页而不是28页。


的数据
我本来希望能够把这合并这3个步骤合二为一,有没有更简单的解决方案?

相关问题