Как извлечь жирный текст из PDF, используя R - PullRequest
0 голосов
/ 20 ноября 2018

Я искал в SO, и самый близкий к ответу ответ был здесь .Но мое требование состоит в том, чтобы получить более простой и элегантный способ выделить жирный текст из простого абзаца текста в формате pdf.Пакет pdftools извлекает только текстовый компонент.Кто-нибудь знает, есть ли какой-нибудь другой способ просто обнаружить жирные токены (или слова) из фрагмента текста в pdf.Я использую R, поэтому любезно ограничивайтесь предложениями в R.

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

Наряду с гибким инструментарием, наука о данных регулярно требует нестандартного мышления (по крайней мере, в моей профессии).

Но, во-первых, кое-что о файлах PDF.

Я не думаю, что они такие, как вы думаете.«Жирный» (или «курсив» и т. Д.) Не является «метаданными».Вам следует потратить некоторое время на чтение PDF-файлов, потому что это сложные, неприятные, злые вещи, с которыми вы, вероятно, часто сталкиваетесь при работе с данными.Прочтите это - https://stackoverflow.com/a/19777953/1457051 - чтобы увидеть, что в действительности означает поиск жирного текста (перейдите по ссылке на решение 1.8.x Java pdfbox).

Возвращаясь к нашему нерегулярному намеченному ответу

Хотя я являюсь одним из САМЫХ ГРОМКИХ сторонников R, не все должно быть сделано или должно быть сделано в R. Конечномы будем использовать R для , в конечном итоге получить ваш жирный текст, но мы будем использовать вспомогательную утилиту командной строки для этого.

Пакет pdftools основан на библиотеке poppler.Он поставляется с источником, так что «я просто пользователь R», вероятно, не имеет полного набора инструментов poppler в своей системе.

Пользователи Mac могут использовать Homebrew для (как только вы настроите Homebrew):

  • brew install poppler

Люди Linux знают, как что-то делать.Люди Windows потеряны навсегда (для вас есть двоичные файлы poppler, но ваше время будет лучше потратить на переключение на настоящую операционную систему).

Как только вы это сделаете, вы можете использовать нижечтобы достичь своей цели.

Сначала мы сделаем вспомогательную функцию с большим количеством защитных бамперов:

#' Uses the command-line pdftohtml function from the poppler library
#' to convert a PDF to HTML and then read it in with xml2::read_html()
#'
#' @md
#' @param path the path to the file [path.expand()] will be run on this value
#' @param extra_args extra command-line arguments to be passed to `pdftohtml`.
#'        They should be supplied as you would supply arguments to the `args`
#'        parameter of [system2()].
read_pdf_as_html <- function(path, extra_args=character()) {

  # make sure poppler/pdftohtml is installed
  pdftohtml <- Sys.which("pdftohtml")
  if (pdftohtml == "") {
    stop("The pdftohtml command-line utility must be installed.", call.=FALSE)
  }

  # make sure the file exists
  path <- path.expand(path)
  stopifnot(file.exists(path))

  # pdf's should really have a PDF extension
  stopifnot(tolower(tools::file_ext(path)) == "pdf")

  # get by with a little help from our friends
  suppressPackageStartupMessages({
    library(xml2, warn.conflicts = FALSE, quietly = TRUE)
    library(rvest, warn.conflicts = FALSE, quietly = TRUE)
  })

  # we're going to do the conversion in a temp directory space
  td <- tempfile(fileext = "_dir")
  dir.create(td)
  on.exit(unlink(td, recursive=TRUE), add=TRUE)

  # save our current working directory
  curwd <- getwd()
  on.exit(setwd(curwd), add=TRUE)

  # move to the temp space
  setwd(td)
  file.copy(path, td)

  # collect the extra arguments
  c(
    "-i" # ignore images
  ) -> args

  args <- c(args, extra_args, basename(path), "r-doc") # saves it to r-doc-html.html

  # this could take seconds so inform users what's going on
  message("Converting ", basename(path), "...")

  # we'll let stderr display so you can debug errors
  system2(
    command = pdftohtml,
    args = args,
    stdout = TRUE
  ) -> res

  res <- gsub("^Page-", "", res[length(res)])
  message("Converted ", res, " pages")

  # this will need to be changed if poppler ever does anything different
  xml2::read_html("r-docs.html")

}

Теперь мы будем использовать ее:

doc <- read_pdf_as_html("~/Data/Mulla__Indian_Contract_Act2018-11-12_01-00.PDF")

bold_tags <- html_nodes(doc, xpath=".//b")

bold_words <- html_text(bold_tags)

head(bold_words, 20)
##  [1] "Preamble"                                                                                   
##  [2] "WHEREAS it is expedient to define and amend certain parts of the law relating to contracts;"
##  [3] "History"                                                                                    
##  [4] "Ancient and Medieval Period"                                                                
##  [5] "The Introduction of English Law Into India"                                                 
##  [6] "Mofussal Courts"                                                                            
##  [7] "Legislation"                                                                                
##  [8] "The Indian Contract Act 1872"                                                               
##  [9] "The Making of the Act"                                                                      
## [10] "Law of Contract Until 1950"                                                                 
## [11] "The Law of Contract after 1950"                                                             
## [12] "Amendments to This Act"                                                                     
## [13] "Other Laws Affecting Contracts and Enforcement"                                             
## [14] "Recommendations of the Indian Law Commission"                                               
## [15] "Section 1."                                                                                 
## [16] "Short title"                                                                                
## [17] "Extent, Commencement."                                                                      
## [18] "Enactments Repealed."                                                                       
## [19] "Applicability of the Act"                                                                   
## [20] "Scheme of the Act"

length(bold_words)
## [1] 1939

Java вообще не требуется, и у вас есть смелые слова .

Если вы действительно хотите пойти по маршруту pdfbox-app, как отметил Ральф, вы можете использовать эту оболочку, чтобыс ним проще работать:

read_pdf_as_html_with_pdfbox <- function(path) {

  java <- Sys.which("java")
  if (java == "") {
    stop("Java binary is not on the system PATH.", call.=FALSE)
  }

  # get by with a little help from our friends
  suppressPackageStartupMessages({
    library(httr, warn.conflicts = FALSE, quietly = TRUE)
    library(xml2, warn.conflicts = FALSE, quietly = TRUE)
    library(rvest, warn.conflicts = FALSE, quietly = TRUE)
  })

  path <- path.expand(path)
  stopifnot(file.exists(path))

  # pdf's should really have a PDF extension
  stopifnot(tolower(tools::file_ext(path)) == "pdf")

  # download the pdfbox "app" if not installed
  if (!dir.exists("~/.pdfboxjars")) {
    message("~/.pdfboxjars not found. Creating it and downloading pdfbox-app jar...")
    dir.create("~/.pdfboxjars")
    httr::GET(
      url = "http://central.maven.org/maven2/org/apache/pdfbox/pdfbox-app/2.0.12/pdfbox-app-2.0.12.jar",
      httr::write_disk(file.path("~/.pdfboxjars", "pdfbox-app-2.0.12.jar")),
      httr::progress()
    ) -> res
    httr::stop_for_status(res)
  }

  # we're going to do the conversion in a temp directory space
  tf <- tempfile(fileext = ".html")
  on.exit(unlink(tf), add=TRUE)

  c(
    "-jar",
    path.expand(file.path("~/.pdfboxjars", "pdfbox-app-2.0.12.jar")),
    "ExtractText",
    "-html",
    path,
    tf
  ) -> args

  # this could take seconds so inform users what's going on
  message("Converting ", basename(path), "...")

  system2(
    command = java,
    args = args
  ) -> res

  xml2::read_html(tf)

}
0 голосов
/ 23 ноября 2018

Этот ответ основан на ответах, полученных от @hrbmstr и @ralf.Так что спасибо им.Я сделал ответы проще (в основном, исключая особенности преобразования HTML и именования файлов).Также он предназначен для пользователей MAC OS (возможно, и для LINUX) - не уверен насчет парней с Windows.

Полагаю, на вашем компьютере установлено pdftohtml.Если не использовать brew install pdftohtml.Если на вашем MAC нет homebrew , то сначала установите его.Ссылка предоставляется, чтобы помочь вам для доморощенного .

Как только вы убедитесь, что на компьютере установлена ​​pdftohtml, перейдите к этой функции R, чтобы извлечь жирный шрифт из любого документа PDF.

library(magrittr)
library(rvest)
library(stringr)

# pass a pdf file in current directory to this function
extr_bold <- function(file) {
  basefile <- str_remove(file,"\\.pdf|\\.PDF")
  htmlfile <- paste0(basefile,"s",".html")
  if(!exists(htmlfile) ) 
    system2("pdftohtml",args = c("-i",file),stdout=NULL)
  nodevar <- read_html(htmlfile)
  x <- html_nodes(nodevar,xpath = ".//b")
  html_text(x)
}
0 голосов
/ 21 ноября 2018

Вам не нужно использовать tabularizer, но я не знаю способа, который не включает Java.Я надеялся, что Apache Tika через пакет rtika может быть использован.Однако полужирный текст не отображается как таковой .Однако можно использовать pdfbox , как показано в этом билете:

 java -jar <pdfbox-jar> ExtractText -html <pdf-file> <html-file>

Эта команда обычно запускается в оболочке, но вы также можете использовать system(2) из R. ЗатемR используйте

html <- xml2::read_html(<html-file>)
bold <- xml2::xml_find_all(html, '//b')
head(xml2::xml_contents(bold))

для обработки файла HTML.С вашим документом это возвращает

{xml_nodeset (6)}
[1] Preamble\n
[2] WHEREAS it is expedient to define and amend certain parts of the law relating to contracts;\n
[3] History\n
[4] Ancient and Medieval Period\n
[5] The Introduction of English Law Into India\n
[6] Mofussal Courts\n
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...