上传Word文件以通过TIKA REST提取文本

问题描述 投票:0回答:1

我正在尝试通过其REST API调用Apache-TIKA。我已经能够成功上传PDF文档并通过CURL返回该文档的文本

curl -X PUT --data-binary @<filename>.pdf http://localhost:9998/tika --header "Content-type: application/pdf"

像这样翻译成INDY:

function GetPDFText(const FileName: String): String;
var
  IdHTTP:  TIdHTTP;
  Params: TIdMultiPartFormDataStream;
begin
  IdHTTP := TIdTTP.Create;
  try
    Params := TIdMultiPartFormDataStream.Create;
    try
      Params.Add('file', FileName, 'application/pdf')
      Result := IdHTTP.PUT('http://localhost:9998/tika', Params);
    finally
      Params.Free;
    end;    
  finally
    IdHTTP.Free;
  end;
end;

现在我要上传Word文档(.docx)我以为,将文件添加到Params时,我需要做的就是更改内容类型,但这似乎不会产生任何结果,尽管我没有报告任何错误。我能够获得以下CURL命令正常运行]

CURL -T <myDOCXfile>.docx http://localhost:9998/tika --header "Content-type: application/vnd.openxmlformats-officedocument.wordprocessingml.document"

如何将我的HTTP调用从CURL -X PUT修改为CURL -T?

delphi lazarus apache-tika indy10
1个回答
0
投票

您的实现中至少有两个问题:

  1. 您从CURL -X PUTTIdHTTP的翻译是错误的。
  2. 您未指定Accept HTTP标头以特定格式检索提取的文本。

如何将curl -X PUT翻译成印地语?

首先,请清楚在以下情况下curl -X PUT --data-binary @<filename> <url>curl -T <filename> <url>相同:

  • [<url>的方案是HTTPHTTPS
  • [<url>不以/结尾

因此,在您的情况下使用一种或另一种都没有关系。另请参阅curl documentation

[其次,TIdMultiPartFormDataStream是为与POST动词一起使用而设计的,但是没有什么可以阻止您将其传递给TIdHTTP.Put的,因为它是直接从TStream派生的。甚至invariant of TIdHTTP.Post的专用TIdHTTP.Post方法都接受TIdHTTP

function Post(AURL:string; ASource:TIdMultiPartFormDataStream):string;重载;

要将文件上传到服务,只需使用TIdMultiPartFormDataStream方法作为参数,并使用TIdHTTP.Put作为参数,同时在HTTP标头中提供要上传的文件的正确内容类型。

最后,您尝试从文档中提取纯文本,但是没有指定服务应返回的内容类型。这是通过TFileStream HTTP标头完成的。 Accept的默认实例的属性TIdHTTP初始化为IdHTTP.Request.Accept(可能因Indy版本而异)。因此,默认情况下,Tika将返回HTML格式的文本。要获取纯文本,应将其更改为'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'

固定执行:

'text/plain; charset=utf-8'

根据uses IdGlobal, IdHTTP; function GetDocumentText(const FileName, ContentType: string): string; var IdHTTP: TIdHTTP; Stream: TIdReadFileExclusiveStream; begin IdHTTP := TIdHTTP.Create; try IdHTTP.Request.Accept := 'text/plain; charset=utf-8'; IdHTTP.Request.ContentType := ContentType; Stream := TIdReadFileExclusiveStream.Create(FileName); try Result := IdHTTP.Put('http://localhost:9998/tika', Stream); finally Stream.Free; end; finally IdHTTP.Free; end; end; function GetPDFText(const FileName: string): string; const PDFContentType = 'application/pdf'; begin Result := GetDocumentText(FileName, PDFContentType); end; function GetDOCXText(const FileName: string): string; const DOCXContentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; begin Result := GetDocumentText(FileName, DOCXContentType); end; ,它还支持发布多部分表单数据。如果您坚持使用此方法,则应在实现中将目标资源更改为Tika's documentation并切换到/tika/form方法:

Post

为什么原始的实施方案可以处理PDF文件?

当您通过function GetDocumentText(const FileName, ContentType: string): string; var IdHTTP: TIdHTTP; FormData: TIdMultiPartFormDataStream; begin IdHTTP := TIdHTTP.Create; try IdHTTP.Request.Accept := 'text/plain; charset=utf-8'; FormData := TIdMultiPartFormDataStream.Create; try FormData.AddFile('file', FileName, ContentType); { older Indy versions: FormData.Add(...) } Result := IdHTTP.Post('http://localhost:9998/tika/form', FormData); finally FormData.Free; end; finally IdHTTP.Free; end; end; 进行Post多部分表单数据时,Indy会自动将请求的内容类型设置为TIdHTTP。当您'multipart/form-data; boundary=...whatever...'(除非在执行请求之前先Put)数据并且因此set it manually保持空白时,情况并非如此。现在,我只能猜测,当Tika看到空的内容类型时,它会退回到某种默认类型(可能是PDF),并且仍然可以从多部分请求中读取文档。

© www.soinside.com 2019 - 2024. All rights reserved.