【问题标题】:Error trying to read a PDF using readPDF from the tm package尝试使用 tm 包中的 readPDF 读取 PDF 时出错
【发布时间】:2013-08-01 11:48:05
【问题描述】:

(Windows 7/R 版本 3.0.1)

下面的命令和产生的错误:

> library(tm)
> pdf <- readPDF(PdftotextOptions = "-layout")
> dat <- pdf(elem = list(uri = "17214.pdf"), language="de", id="id1")

Error in file(con, "r") : cannot open the connection
In addition: Warning message:
In file(con, "r") :
  cannot open file 'C:\Users\Raffael\AppData\Local\Temp
    \RtmpS8Uql1\pdfinfo167c2bc159f8': No such file or directory

我该如何解决这个问题?


编辑我

(根据 Ben 的建议和描述 here

我下载了Xpdf复制32位版本到 C:\Program Files (x86)\xpdf32 和 64 位版本 C:\Program Files\xpdf64

环境变量 pdfinfopdftotext 分别指代 32 位(使用 R 32 位测试)或 64 位(使用 R 64 位测试)的可执行文件


编辑二

一个非常令人困惑的观察是,从一个新的会话开始(tm 未加载)单独的最后一个命令会产生错误:

> dat <- pdf(elem = list(uri = "17214.pdf"), language="de", id="id1")

Error in file(con, "r") : cannot open the connection
In addition: Warning message:
In file(con, "r") :
  cannot open file 'C:\Users\Raffael\AppData\Local\Temp\RtmpKi5GnL
     \pdfinfode8283c422f': No such file or directory

我完全不明白这一点,因为函数变量尚未由 tm.readPDF 定义。下面你会发现函数 pdf 指的是“自然”以及 tm.readPDF 返回的内容:

> pdf

function (elem, language, id) 
{
    meta <- tm:::pdfinfo(elem$uri)
    content <- system2("pdftotext", c(PdftotextOptions, shQuote(elem$uri), 
        "-"), stdout = TRUE)
    PlainTextDocument(content, meta$Author, meta$CreationDate, 
        meta$Subject, meta$Title, id, meta$Creator, language)
}
<environment: 0x0674bd8c>

> library(tm)
> pdf <- readPDF(PdftotextOptions = "-layout")
> pdf

function (elem, language, id) 
{
    meta <- tm:::pdfinfo(elem$uri)
    content <- system2("pdftotext", c(PdftotextOptions, shQuote(elem$uri), 
        "-"), stdout = TRUE)
    PlainTextDocument(content, meta$Author, meta$CreationDate, 
        meta$Subject, meta$Title, id, meta$Creator, language)
}
<environment: 0x0c3d7364>

显然没有区别 - 那么为什么要使用 readPDF 呢?


编辑 III

pdf文件位于:C:\Users\Raffael\Documents

> getwd()
[1] "C:/Users/Raffael/Documents"

编辑 IV

pdf() 中的第一条指令是对 tm:::pdfinfo() 的调用 - 错误是在前几行引起的:

> outfile <- tempfile("pdfinfo")
> on.exit(unlink(outfile))
> status <- system2("pdfinfo", shQuote(normalizePath("C:/Users/Raffael/Documents/17214.pdf")), 
+                   stdout = outfile)
> tags <- c("Title", "Subject", "Keywords", "Author", "Creator", 
+           "Producer", "CreationDate", "ModDate", "Tagged", "Form", 
+           "Pages", "Encrypted", "Page size", "File size", "Optimized", 
+           "PDF version")
> re <- sprintf("^(%s)", paste(sprintf("%-16s", sprintf("%s:", 
+                                                       tags)), collapse = "|"))
> lines <- readLines(outfile, warn = FALSE)
Error in file(con, "r") : cannot open the connection
In addition: Warning message:
In file(con, "r") :
  cannot open file 'C:\Users\Raffael\AppData\Local\Temp\RtmpquRYX6\pdfinfo8d419174450':   No such file or direc

显然tempfile() 根本不会创建文件。

> outfile <- tempfile("pdfinfo")
> outfile
[1] "C:\\Users\\Raffael\\AppData\\Local\\Temp\\RtmpquRYX6\\pdfinfo8d437bd65d9"

文件夹C:\Users\Raffael\AppData\Local\Temp\RtmpquRYX6 存在并包含一些文件,但没有一个名为pdfinfo8d437bd65d9

【问题讨论】:

标签: r tm


【解决方案1】:

有趣的是,在我的机器上重新启动后pdf 是一个将图像转换为 PDF 的功能:

 getAnywhere(pdf)
A single object matching ‘pdf’ was found
It was found in the following places
  package:grDevices
  namespace:grDevices [etc.]

但是回到将 PDF 文件作为文本读取的问题,摆弄 PATH 有点碰巧(如果您在多台不同的计算机上工作,这很烦人),所以我认为最简单和最安全的方法是使用system 作为Tony Breyal describes here 调用pdf2text

在你的情况下它会是(注意两组引号):

system(paste('"C:/Program Files/xpdf64/pdftotext.exe"', 
             '"C:/Users/Raffael/Documents/17214.pdf"'), wait=FALSE)

如果您有许多 PDF 文件,可以使用 *apply 函数或循环轻松扩展此功能。

【讨论】:

  • 简单的解决方法。为什么不。似乎有几个问题。首先 tempfile 不是创建文件。我使用 file.create 覆盖了它,然后遇到了进一步的问题。这不值得麻烦。
  • 是的,很抱歉,它没有解决您透露的复杂性,但它可以完成工作。
猜你喜欢
  • 2013-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-22
  • 2018-07-15
  • 2019-05-19
  • 2021-10-05
  • 2013-04-15
相关资源
最近更新 更多