gpt4 book ai didi

在超链接位置提取 PDF 文本

转载 作者:行者123 更新时间:2023-12-02 02:30:24 25 4
gpt4 key购买 nike

有人知道某种(免费)SDK 可以在 PDF 文档中超链接将您带到的位置(在同一 PDF 文档中)开始文本提取吗?这些链接最终会将我们带到特定页面上的特定点。

更具体地说,我们需要一个程序来解析包含测试问题和答案(以及每个问题/答案的相关注释)的 pdf 文档,并仅将我们需要的相关部分导出到文本文件。

基本上,PDF 文档在文档的开头有测试问题,每个问题中都有一个超链接,指向它的答案和 PDF 文档另一部分的相关注释。

附言- 使用以下语言之一:C++、Java、VB.net、C#.net、javascript附言- 仅限免费软件

最佳答案

这比听起来难 - 您可能需要重新考虑您的问题。文档内超链接通常是通过链接注释完成的,其中目标设置为“Goto View”操作。该 View 不一定包括边界甚至点。有时它只是一页(当前缩放)或一页(适合宽度)或一页(在顶部,特定缩放)。它甚至比这更复杂,因为链接目标可能是一棵按顺序执行的操作树,每个操作都是 18 种不同的可能操作类型之一,包括可用于驱动查看者前往特定目标的 javascript。

我想您也会遇到“链接指向您的地方”的问题。

您可以使用 Atalasoft dotAnnotate 和 PDF 文本提取插件在 C# 中完成很多此类任务(免责声明,我在 Atalasoft 工作,编写了 PDF->annotations 导入器,并且曾经在 Acrobat v 1 上为 Adob​​e 工作, 2, & 3).不,很抱歉,它不是免费软件。

这是我的做法(免责声明 - 这就在我的脑海中):

class PageAnnots : KeyValuePair<int, List<PdfLinkData>> { }

public PageAnnots GetPageLinkDestinations(Stream stm)
{
PdfAnnotationDataImporter importer = new PdfAnnotationDataImporter(stm);
List<PageAnnots> pageAnnots = new List<PageAnnots>();

try {
importer.Load();
// this gets all annotations on all pages. On long docs, this will be time consuming
AnnotationDataCollection allAnnots = importer.Import();
int pageNo = 0;
// allAnnots is a collection of LayerData, each LayerData object being a collection
// of annots for a page. The collection is empty if there are no annots
foreach (AnnotationData pageOfAnnots in allAnnots) {
List<PdfLinkData> linkAnnots = new List<PdfLinkData>();
LayerData pageLayer = pageOfAnnots as LayerData;
if (pageLayer != null) {
// filter out each annot that is a link
foreach (AnnotationData annot in pageLayer.Items) {
PdfLinkData link = annot as PdfLinkData;
if (link != null)
linkAnnots.Add(link);
}
}
if (linkAnnots.Count > 0) {
pageAnnots.Add(new PageAnnots(pageNo, linkAnnots));
}
pageNo++;
}
}
catch (Exception err) {
// keep it? drop it?
}

return pageAnnots;
}

此时,我们已将其简化为键值对的集合,每个键都是一个页码,每个值都是代表该页面上链接的 PdfLinkData 对象的非空列表。

从那里,您可以迭代这个集合并尝试像这样找出目的地:

private int PageFromDestination(PdfDestination dest)
{
PdfIndexedPageReference pageRef = dest.Page as PdfIndexedPageReference;
return pageRef == null ? -1 : pageRef.PageIndex;
}

public void FigureDestination(PdfLinkData link)
{
PdfActionList actions = link.ClickAction;
foreach (PdfAction action in actions) {
PdfGoToViewAction gotoView = action as PdfGoToViewAction;
if (action == null)
continue;
// this only pulls the page from the destination. The dest
// may also contain information about the view. I'm assuming you
// only want the page number
int page = PageFromDestination(gotoView.Destination);
if (page >= 0) {
// here's where you step in - the click action could be
// a long chain of things including several GoToView actions.
// it's up to you to decide what you want to do. Handle only
// action lists of length 1? Stop at first GoToView?
// aggregate them all?
}
}
}

当您查看这段代码时,您会想知道为什么在索引页面引用、操作类型和操作列表方面存在这种抽象级别?答案是 GoToView 操作也可以引用另一个文档 - 跨文档链接在 PDF 中有效。虽然 dotAnnotate 现在不支持它们,但它准备在未来支持它们。同样,该操作可能指示转到嵌入式 PDF 文档中的 View (是的,您可以在 PDF 中嵌入 PDF)。

您需要注意,dotAnnotate 为您提供了一组有限的相当高级的对象,并不要求您了解和理解 PDF 规范(太多)。过去,我们曾尝试将非常精细的 API 发布到 TIFF 之类的东西中,但发现我们的客户并不喜欢它们。因此,我们试图猜测我们的客户可能想要和需要什么,并创建更容易理解的 API。

iText 和 iTextSharp 为您提供了对 API 的非常精细的级别控制,但您需要了解 PDF 规范以获得您需要的内容。

例如,要进行注释提取,您必须打开文档,获取页面目录,遍历页面树,找到所有具有 Annots 键的页面字典,遍历 Annots 数组,搜索其中的每个字典对于具有值/Annot 的键/Type 和对于具有值/Link 的键/SubType,然后提取键/Dest 的值(如果存在)并且如果该值不为空则使用该值,否则查看键/A 和开始遍历操作树以查找键/Type 设置为/GoTo (IIRC) 的操作,然后从那里开始。

目的地可以是直接目的地,也可以是命名目的地。如果它是一个命名的目的地,你将不得不回到文档目录并拉出名称树并在命名的目的地中搜索名称,当你找到它时,拉出那里的信息。

是的,您可以使用 iText 或其他类似的 PDF 解析器,但您需要执行所有这些步骤,除非库创建者中的一位好心地为您完成了这些。

关于在超链接位置提取 PDF 文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3992993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com