【问题标题】:How to extract bold and non-bold text from pdf using R如何使用R从pdf中提取粗体和非粗体文本
【发布时间】:2018-09-07 06:16:57
【问题描述】:

我正在使用 R 提取文本。下面的代码可以很好地从 pdf 中提取非粗体文本,但它忽略了粗体部分。有没有办法同时提取粗体 非粗体文本?

 news <-'http://www.frbe-kbsb.be/sites/manager/ICN/14-15/ind01.pdf'
 library(pdftools)
 library(tesseract)
 library(tiff)
 info <- pdf_info(news)
 numberOfPageInPdf <- as.numeric(info[2])
 numberOfPageInPdf
 for (i in 1:numberOfPageInPdf){
      bitmap <- pdf_render_page(news, page=i, dpi = 300, numeric = TRUE)
      file_name <- paste0("page", i, ".tiff") 
      file_tiff <- tiff::writeTIFF(bitmap, file_name)
      out <- ocr(file_name)
      file_txt <- paste0("text", i, ".txt") 
      writeLines(out, file_txt)
    }

【问题讨论】:

标签: r pdf text extract


【解决方案1】:

无需通过 PDF -> TIFF -> OCR 循环,因为pdftools::pdf_text() 可以直接读取此文件:

stringi::stri_split(pdf_text(news), regex = "\n")

【讨论】:

  • 我仍然找不到从 pdf 文件中提取粗体文本的优雅方法?我认为我们不需要用制表符和定位区域等使其复杂化。
  • @SanjayMehrotra 我不明白你评论的上下文。如果此处提供的解决方案不适合您的问题,请随时发布新问题。
  • 问题:如何使用 R 但不使用制表符包识别 pdf 文件中的粗体文本。原因:如果文件中没有表格,我觉得 Tabuliser 是一种过度杀伤力。对于纯文本段落,我们不需要识别文本的区域。是否有任何其他软件包或制表符中是否有直接的方法来提取粗体字符?谢谢。
  • @SanjayMehrotra 根据我的经验,tabularizer 非常适合提取表格材料,即使没有指定定位区域。但是,如果您只对纯文本段落感兴趣,我的回答中使用的pdftools::pdf_text() 可能就足够了。但是,它不会以任何方式区分字体粗细(粗体、正常、浅色……)。
  • @SanjayMehrotra 问一个新问题是我最初的建议。但请记住,要求工具/库的问题在 SO 上被视为离题。
【解决方案2】:

我喜欢为此使用tabulizer 库。这是一个小例子:

devtools::install_github("ropensci/tabulizer")
library(tabulizer)

news <-'http://www.frbe-kbsb.be/sites/manager/ICN/14-15/ind01.pdf'

# note that you need to specify UTF-8 as the encoding, otherwise your special characters
# won't come in correctly

page1 <- extract_tables(news, guess=TRUE, page = 1, encoding='UTF-8')

page1[[1]]

      [,1] [,2]                    [,3]       [,4]                [,5]    [,6]                [,7]      
 [1,] ""   "Division: 1"           ""         ""                  ""      ""                  "Série: A"
 [2,] ""   "514"                   ""         "Fontaine 1 KBSK 1" ""      ""                  "303"     
 [3,] "1"  "62529 WIRIG ANTHONY"   ""         "2501 1⁄2-1⁄2"      "51560" "CZEBE ATTILLA"     "2439"    
 [4,] "2"  "62359 BRUNNER NICOLAS" ""         "2443 0-1"          "51861" "PICEU TOM"         "2401"    
 [5,] "3"  "75655 CEKRO EKREM"     ""         "2393 0-1"          "10391" "GEIRNAERT STEVEN"  "2400"    
 [6,] "4"  "50211 MARECHAL ANDY"   ""         "2355 0-1"          "35181" "LEENHOUTS KOEN"    "2388"    
 [7,] "5"  "73059 CLAESEN PIETER"  ""         "2327 1⁄2-1⁄2"      "25615" "DECOSTER FREDERIC" "2373"    
 [8,] "6"  "63614 HOURIEZ CLEMENT" ""         "2304 1⁄2-1⁄2"      "44954" "MAENHOUT THIBAUT"  "2372"    
 [9,] "7"  "60369 CAPONE NICOLA"   ""         "2283 1⁄2-1⁄2"      "10430" "VERLINDE TIEME"    "2271"    
[10,] "8"  "70653 LE QUANG KIM"    ""         "2282 0-1"          "44636" "GRYSON WOUTER"     "2269"    
[11,] ""   ""                      "< 2361 >" "12 - 20"           ""      "< 2364 >"          ""      

如果您只关心部分表格,也可以使用locate_areas 函数指定特定区域。请注意,要让locate_areas 工作,我必须先在本地下载文件;使用 URL 返回错误。

您会注意到,每个表在返回的列表中都是其自己的元素。

这是一个使用自定义区域仅选择每个页面上的第一个表的示例:

customArea <- extract_tables(news, guess=FALSE, page = 1, area=list(c(84,27,232,569), encoding = 'UTF-8')

这也是比使用 OCR(光学字符识别)库tesseract 更直接的方法,因为您不依赖 OCR 库将像素排列转换回文本。在数字 PDF 中,每个文本元素都有一个 x 和 y 位置,tabulizer 库使用该信息来检测表启发式并提取合理格式化的数据。你会发现你还有一些清理工作要做,但这很容易处理。

编辑:只是为了好玩,这里有一个用data.table开始清理的小例子

library(data.table)

cleanUp <- setDT(as.data.frame(page1[[1]]))

cleanUp[ ,  `:=` (Division = as.numeric(gsub("^.*(\\d+{1,2}).*", "\\1", grep('Division', cleanUp$V2, value=TRUE))),
  Series = as.character(gsub(".*:\\s(\\w).*","\\1", grep('Série:', cleanUp$V7, value=TRUE))))
  ][,ID := tstrsplit(V2," ", fixed=TRUE, keep = 1)
  ][, c("V1", "V3") := NULL
  ][-grep('Division', V2, fixed=TRUE)]

在这里,我们已将 DivisionSeriesID 移到各自的列中,并删除了 Division 标题行。这只是大体思路,需要稍加改进才能适用于所有 27 页。

                       V2                V4    V5                V6   V7 Division Series    ID
 1:                   514 Fontaine 1 KBSK 1                          303        1      A   514
 2:   62529 WIRIG ANTHONY      2501 1/2-1/2 51560     CZEBE ATTILLA 2439        1      A 62529
 3: 62359 BRUNNER NICOLAS          2443 0-1 51861         PICEU TOM 2401        1      A 62359
 4:     75655 CEKRO EKREM          2393 0-1 10391  GEIRNAERT STEVEN 2400        1      A 75655
 5:   50211 MARECHAL ANDY          2355 0-1 35181    LEENHOUTS KOEN 2388        1      A 50211
 6:  73059 CLAESEN PIETER      2327 1/2-1/2 25615 DECOSTER FREDERIC 2373        1      A 73059
 7: 63614 HOURIEZ CLEMENT      2304 1/2-1/2 44954  MAENHOUT THIBAUT 2372        1      A 63614
 8:   60369 CAPONE NICOLA      2283 1/2-1/2 10430    VERLINDE TIEME 2271        1      A 60369
 9:    70653 LE QUANG KIM          2282 0-1 44636     GRYSON WOUTER 2269        1      A 70653
10:                                 12 - 20                < 2364 >             1      A    NA

【讨论】:

  • 我在安装时遇到了麻烦。这是解决方案包tabulizer library(devtools) devtools::install_github("ropensci/tabulizer")
  • @emeryville 谢谢,我忘了它在 cran.r 上不可用。更新了我的答案以反映这一点
  • 我有一些希望,但不幸的是我安装 tabulizer 的解决方案不起作用,这个either
  • @emeryville 您可能还需要安装 Java,请参阅此处的安装部分:github.com/ropensci/tabulizer
猜你喜欢
  • 2019-04-23
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多