从 web delphi 中提取信息的最佳方法

Posted

技术标签:

【中文标题】从 web delphi 中提取信息的最佳方法【英文标题】:best way to extract info from the web delphi 【发布时间】:2012-02-09 06:42:52 【问题描述】:

我想知道是否有更好的方法从网页中提取信息,而不是解析 html 以获取我正在搜索的内容。即:从“imdb.com”中提取电影评分

我目前正在使用 IndyHttp 组件来获取页面,并且我正在使用 strUtils 来解析文本,但内容有限。

【问题讨论】:

网页不一定是有效的 XHTML 文档,并且 javascript 可以更改 DOM,所以我认为您应该从嵌入式 Web 浏览器(如 TWebBrowser 或 Chromium Embedded)探索 DOM。 依赖 DOM 和 TWebBrowser 应该是最后的手段,因为它会很慢并且容易出错。如果要抓取的数据来自 JavaScript,可以直接从 JavaScript 抓取。如果它填充了某种形式的 Ajax,则可以直接编写并获取 Ajax URL。无论浏览器做什么,都可以手动模拟。 【参考方案1】:

所有发布的答案都很好地涵盖了您的一般问题。我通常遵循类似于 Cosmin 详述的策略。我使用 wininet 和 regex 来满足我的大部分网络提取需求。

但是,让我在提取 imdb 资格的特定子问题中添加我的两分钱。 IMDBAPI.COM提供查询接口返回json码,对于这类搜索非常方便。

因此,获得 imdb 评级的一个非常简单的命令行程序将是......

program imdbrating;
$apptype console
uses htmlutils;

function ExtractJsonParm(parm,h:string):string;
 var r:integer;
 begin
  r:=pos('"'+Parm+'":',h);
  if r<>0 then 
    result:=copy(h,r+length(Parm)+4,pos(',',copy(h,r+length(Parm)+4,length(h)))-2)
  else
    result:='N/A';
 end;
    
var h:string;
begin
  h:=HttpGet('http://www.imdbapi.com/?t=' + UrlEncode(ParamStr(1)));
  writeln(ExtractJsonParm('Rating',h));
end.

【讨论】:

+1 表示比“屏幕抓取”更不可能打破的答案。【参考方案2】:

在抓取网站时,您不能依赖信息的可用性。 IMDB 可能会检测到您的抓取并试图阻止您,或者他们可能会频繁更改格式以使其更加困难。

因此,您应该始终尝试使用受支持的 API 或 RSS 提要,或者至少获得网站的许可来汇总他们的数据,并确保您遵守他们的条款。通常,您必须为此类访问付费。在未经许可的情况下抓取网站可能会使您在几个法律方面(拒绝服务和知识产权)承担责任。

这是 IMDB 的statement:

您不得使用数据挖掘、机器人、屏幕抓取或类似功能 我们网站上的在线数据收集和提取工具。

要回答您的问题,更好的方法是使用网站提供的方法。对于非商业用途,如果您遵守他们的terms,您可以download the IMDB database directly 并使用那里的数据而不是抓取他们的网站。只需经常更新您的数据库,这是比抓取网站更好的解决方案。您甚至可以围绕它包装自己的 Web API。评级以独立表格的形式提供。

【讨论】:

+1 用于指出屏幕刮擦的危害。顺便说一句,否决票是没有根据的。 IMO,这方面的讨论对于任何重要的第三方数据使用都至关重要。【参考方案3】:

我发现简单的正则表达式在处理好网站时非常直观和简单,而 IMDB 是一个很好的网站。

例如,IMDB 的电影 HTML 页面上的电影分级在 &lt;DIV&gt;class="star-box-giga-star" 中。使用正则表达式非常容易提取。以下正则表达式将从原始 HTML 中提取电影评级到捕获组 1:

star-box-giga-star[^>]*>([^<]*)<

它并不漂亮,但它可以完成工作。正则表达式查找“​​star-box-giga-star”类 id,然后查找终止 DIV&gt;,然后捕获所有内容,直到以下 &lt;。要创建这样的新正则表达式,您应该使用允许检查元素的 Web 浏览器(例如 Crome 或 Opera)。使用 Chrome,您可以简单地查看网页,右键单击要捕获的元素并执行 Inspect element,然后四处寻找可用于创建良好正则表达式的易于识别的元素。在这种情况下,"star-box-giga-star" 类显然很容易识别!在好的网站上找到此类可识别的元素通常没有问题,因为好的网站使用 CSS,而 CSS 需要 ID's 或 class'es 才能正确设置元素的样式。

【讨论】:

【参考方案4】:

如果您正在抓取的页面是有效的 XML,我使用 SimpleXML 来提取信息。效果很好。

资源:

Download link。

【讨论】:

是的,但这不是 php 中已知的 SimpleXML。看这里:blog.spreendigital.de/2011/11/10/… 我也推广 SimpleXML:SimpleXML 非常有限,但在某些情况下非常方便。尽管 OP 寻求解析的替代方法,但您的答案很有价值。如果您提供使用它的示例代码,我会支持它。谢谢。【参考方案5】:

使用 HTML Tidy 将任何 HTML 转换为有效的 XML,然后使用 XML 解析器,可能使用 XPATH 或开发自己的代码(这就是我所做的)。

【讨论】:

【参考方案6】:

处理 RSS 提要 更舒适。

截至发帖时,网站上唯一可用的 RSS 提要是:

在这个日期出生 于该日期死亡 每日投票

不过,您可以致电help desk 来添加新的。

有关 RSS 提要处理的资源:

相关post 在这里。 Super Object Wikipedia。

【讨论】:

以上是关于从 web delphi 中提取信息的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

delphi 怎么从.log中快速提取出需要的信息

如何从 Delphi 中的 PsafeArray 打印信息?

从深度学习的表单中提取文本的最佳方法?

如何从 vtk 中提取纹理以用于搅拌机?

Python。大数据。需要从单元格中提取 Web 浏览器和操作系统用户的偏好。最佳性能方法?

如何让 iPhone 应用程序从 Web 中提取信息?