2

我在研究中处理 PDF,并为一些文本数据编写了 R 刮板。一切正常,我可以通过以下方式读取数据:

library(pdftools)
library(tidyverse)

pdf_text("https://www.bankofengland.co.uk/-/media/boe/files/asset-purchase-facility/2009/2009-
q1.pdf") %>% 
read_lines()

另外我想通过按字体大小过滤来排除表格和脚注

pdf_data("https://www.bankofengland.co.uk/-/media/boe/files/asset-
purchase-facility/2009/2009-q1.pdf", font_info = T, opw = "", upw = 
"")[[2]] %>% 
  filter(font_size>=10) %>%
  group_by(y) %>% 
  summarise(text=paste(text,collapse =" ")) %>% 
  select(-y)  

这适用于前两页。但是,第三页有两列。因此,文本组合为假。有什么简单的解决方法吗?

我看到使用 R 从两列 PDF 中提取文本,但该功能只是修复 pdf_text 输出并且pdf_data我认为不能与它一起使用?

4

1 回答 1

0

pdftools::pdf_ocr_data()是一个tesseract著名的 OCR 软件 ( vignette ) 的包装器。直接使用tesseract意味着我们可以使用它的许多选项中的一部分/全部(参见tesseract_params());其中之一定义了图像中期望的列数。

这可能是这样的:

library(pdftools)
library(tesseract)

# Convert third page of pdf to an image
p3 <- pdftools::pdf_convert("./2009-q1.pdf", page = 3, format = 'tiff',  dpi = 600)

# Tell tesseract engine to expect english in two columns
eng <- tesseract(language = "eng", options = list(tessedit_pageseg_mode = 2))
text <- tesseract::ocr(p3, engine = eng)

# Print result
cat(text)

或者,考虑直接查看tabulizer::extract_text(file)定义列尺寸

编辑

tabulizer::extract_text()可以检测列并自动提取文本:

library(tabulizer)
library(rJava)

t3 <- tabulizer::extract_text("./2009-q1.pdf")
cat(t3)

编辑2

像这样使用已知的列宽pdftools,其中每个列表是一个页面,每个子列表是页面中的一列:

# Define column x-value threshold
xcol <- 300

out <- list()
npages <- length(pdf_data("./2009-q1.pdf"))
for(i in 1:npages){
  temp <- list()
  # Column 1 data
  temp[[1]] <- pdf_data("./2009-q1.pdf", font_info = T, opw = "", upw = "")[[i]] %>% 
    filter(font_size>=10, x < xcol) %>%
    group_by(y) %>% 
    summarise(text=paste(text,collapse =" ")) %>% 
    select(-y)
  # Column 2 data
  temp[[2]] <- pdf_data("./2009-q1.pdf", font_info = T, opw = "", upw = "")[[i]] %>% 
    filter(font_size>=10, x > xcol) %>%
    group_by(y) %>% 
    summarise(text=paste(text,collapse =" ")) %>% 
    select(-y)
  out[[i]] <- temp
}

或者,如果列宽可能会有所不同,也许可以尝试一些类似autothresholdr的方法来估计x.

于 2021-09-16T15:59:07.100 回答