从 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 页面上的电影分级在 <DIV>
和 class="star-box-giga-star"
中。使用正则表达式非常容易提取。以下正则表达式将从原始 HTML 中提取电影评级到捕获组 1:
star-box-giga-star[^>]*>([^<]*)<
它并不漂亮,但它可以完成工作。正则表达式查找“star-box-giga-star”类 id,然后查找终止 DIV
的 >
,然后捕获所有内容,直到以下 <
。要创建这样的新正则表达式,您应该使用允许检查元素的 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 中的 PsafeArray 打印信息?