如何从URL中读取短语以及SWI-Prolog的“open_http / 2”提供什么类型的流?

时间:2015-02-17 20:41:46

标签: http parsing prolog swi-prolog dcg

我正在使用SWI-Prolog library(http/http_open)。根据{{​​3}},"在[http_open(Url, Stream, [])]成功后,可以从Stream中读取数据。"因此,我想也许我可以使用phrase_from_stream/2中的library(pure_input)来装配一个简单的声明性谓词来解析URL中的短语:

phrase_from_url(Url, Phrase) :-
    http_open(Url, In, []),
    phrase_from_stream(Phrase, In),
    close(In).

但我怀疑http_open/3提供的流的种类有一些细微差别;我收到以下错误:

ERROR: set_stream_position/2: stream `<stream>(0x7feebbf5c810)' does not exist (Device not configured)

(我已针对library(http/http_open)文档中提供的示例测试了相同的网址,该文档使用copy_stream_data/2将输出通过管道传输到user_output,并且它有效。所以我知道网址没有错。)

我了解到我可以将网址中的数据下载到字符串,代码列表或文本文件中,然后使用我们的堂兄phrase/n。但我希望有人可以帮我通知......

  1. ...使用DCG解析来自网址的数据的优雅/标准解决方案
  2. ...也许可以深入了解为什么我们不能在某些流上使用phrase_from_stream/2,因为人们可能会天真地希望。

2 个答案:

答案 0 :(得分:1)

目前,library(pure_input) 不支持支持非重新定位流。这就是问题所在。

一种解决方案是阅读所有内容,然后使用正常的phrase。这当然与承诺的“懒惰阅读”不同。

至于“从URL解析数据”,请记住,SWI-Prolog拥有您在网络上找到的许多内容的库:SGML/XML/HTML; JSON; RDF

要从html页面中挑选文本,请参阅示例this simple scraper。相关代码位于scrape/3及其帮助谓词中。它使用SWI-Prolog SGML / XML解析器和library(xpath)

同时,如果你想使用DCG从非重新定位的流中解析,那就太难了。 library(pure_input)甚至不能处理标准输入。根据您的数据结构的不同,您可以使用read_line_to_codes/3(参见示例),如果您的输入按行排列,或read_pending_input/3(如果不是),请阅读一个缓冲区。

答案 1 :(得分:1)

正如Boris所指出的,非重新定位流不能与库(pure_input)一起使用。 read_stream_to_codes / 2,后跟短语/ 2,将为您提供一种实用的方法来测试您的语法与真实数据。

但是,'真实世界'HTML 非常难以解析(即使有内置SGML解析器的支持),因为错误处理不佳。因此,调试DCG可能是一场噩梦,即使是表现良好的语法也是如此。