R/Python:将 PDF 转换为表格

sta*_*oob 2 python ocr tesseract r data-manipulation

我有一个 PDF 图像文件(例如“p1.pdf” - 这是原始文档的扫描副本)保存在我的计算机上 - 该文件看起来像这样(我添加了红线以显示区别):

在此输入图像描述

我想将此 PDF 导入到 R 中,并将其转换为“表对象”。我尝试按照本教程(+ https://cran.r-project.org/web/packages/tesseract/vignettes/intro.html )来做到这一点:

library(tesseract)
library(magick)
library(png)
library(pdftools)
library(tidyverse)

pngfile <- pdftools::pdf_convert('p1.pdf', dpi = 600)
text <- tesseract::ocr(pngfile)
cat(text)

raw_img <- image_read(pngfile)

raw_img %>% 
    image_ocr()
Run Code Online (Sandbox Code Playgroud)

这似乎有效 - 我继续按照教程进行操作:

num_only <- tesseract::tesseract(
  options = list(tessedit_char_whitelist = c(".0123456789 "))
  )

raw_img %>% 
  image_quantize(colorspace = 'gray') %>% 
  image_threshold() %>% 
  image_crop(geometry_area(100, 0, 600, 40)) %>% 
  ocr(engine = num_only) 

combo <- tesseract::tesseract(
    options = list(
      tessedit_char_whitelist = paste0(
        c(letters, LETTERS, " ", ".0123456789 (-)"), collapse = "")
      ))

raw_text <- raw_img %>%
  image_quantize(colorspace = "gray") %>%
  image_transparent("white", fuzz = 22) %>%
  image_background("white") %>%
  image_threshold() %>%
  image_crop(geometry_area(0, 0, 110, 45)) %>%  
  ocr(engine = combo)
Run Code Online (Sandbox Code Playgroud)

现在,我尝试将其转换为表格(“tibble”):

raw_tibble <- raw_text %>% 
  str_split(pattern = "\n") %>% 
  unlist() %>%
  tibble(data = .) 

# A tibble: 68 x 1
   data                                        
   <chr>                                       
 1 "- ALPHABETICAL LISTING ABT"                
 2 "a PlaceYear of Reg"                        
 3 "Name Address Graduation Year"              
 4 ""                                          
 5 "- (John Smith) BC ABC Uni~
 6 ""                                          
 7 "Email: jsmith@gmail.com P"999-999-~
 8 "BCC University 2002"                     
 9 "- Jane Smith HGH Univer~
10 "Email janes@gmail.com "    
# ... with 58 more rows
Run Code Online (Sandbox Code Playgroud)

问题出在此处 - 与教程中进一步整理结果相关的说明似乎非常具体于教程中的示例(即与足球相关)。因此,我无法将它们应用于我的问题。有人可以告诉我如何获取结果并将其转换为看起来更接近原始 PDF 的表格吗?

也许有人可以尝试将我上传的图片保存为 png 文件,看看他们是否可以让这段代码工作?

谢谢!

注1:

  • 因此,我只对“名称”和“地址”列感兴趣
  • 我也对表格的最终格式有很大的灵活性持开放态度。例如“ 401 Fake St Some City, Some State A1C B23 P: 555-555-5555 501 Fake St Some City, Some State A1C B23 p:666-666-6666 601 Fake St Some City, Some State A1C B23 p:666-666-6666”可以全部显示为一行
  • 这意味着在最终表中,2组红线之间的所有“条目”都可以用3列和1行表示

因此,最终的表格可能如下所示:

  id                                 Name                                                                                                                                                                     Address
1  1  (John Smith) Email:jsmith@gmail.com                                                                                                                                                           AB p:999-999-9999
2  2     Jane Smith Email:janes@gmail.com                                                                                                                                                              p:111-111-1111
3  3                          Henry Smith                                                                                                                    201 Fake St,Some City, Some State A1C B23 P:111-222-3333
4  4                          Jason Smith                                                                                                                     301 Fake St Some City,Some State A1C B23 P:555-555-5555
5  5         Luke Smith lsmith2@gmail.com 401 Fake St Some City, Some State A1C B23 P: 555-555-5555 501 Fake St Some City, Some State A1C B23 p:666-666-6666 601 Fake St Some City, Some State A1C B23 p:666-666-6666
                                         Place_Year_Graduation Reg_Year
1 ABC University 2001, BCC University 2002,DEF University 2003     2000
2                  HGH University/2001, Some Other School 2002     2000
3                                               University ABC     1999
4                                                   Univer 123     2005
5                                                  ABC College     2010

final = structure(list(id = 1:5, Name = c(" (John Smith) Email:jsmith@gmail.com", 
"Jane Smith Email:janes@gmail.com", "Henry Smith", "Jason Smith", 
"Luke Smith lsmith2@gmail.com"), Address = c("AB p:999-999-9999", 
"p:111-111-1111", "201 Fake St,Some City, Some State A1C B23 P:111-222-3333", 
"301 Fake St Some City,Some State A1C B23 P:555-555-5555", "401 Fake St Some City, Some State A1C B23 P: 555-555-5555 501 Fake St Some City, Some State A1C B23 p:666-666-6666 601 Fake St Some City, Some State A1C B23 p:666-666-6666"
), Place_Year_Graduation = c("ABC University 2001, BCC University 2002,DEF University 2003", 
"HGH University/2001, Some Other School 2002", "University ABC", 
"Univer 123", "ABC College"), Reg_Year = c(2000, 2000, 1999, 
2005, 2010)), class = "data.frame", row.names = c(NA, -5L))
Run Code Online (Sandbox Code Playgroud)

注 2:我知道这是一个难题,而且 R 可能不是解决这个问题的最合适工具 - 因此,我也愿意使用 Python 来解决这个问题。

Duc*_*mas 5

这需要在 R 或 Python 中完成吗?Tabula https://tabula.technology/是专门为处理这个问题而编写的,并且它做得非常好,尤其是在像您这样的基本表上。