以稳定高效的方式从网页获取数据


11

最近,我了解到,使用正则表达式来解析网站的HTML以获取所需的数据并不是最佳方法。

所以我的问题很简单:那么,什么/最好/最有效且通常稳定的方式来获取此数据?

我应该注意:

  • 没有API
  • 没有其他可以从中获取数据的来源(没有数据库,提要等)
  • 无法访问源文件。(来自公共网站的数据)
  • 假设数据是普通文本,显示在html页面的表格中

我目前在我的项目中使用python,但是独立于语言的解决方案/提示会很好。

附带提出一个问题:当通过Ajax调用构建网页时,您将如何处理?

编辑:

在HTML解析的情况下,我知道没有实际的稳定方法来获取数据。页面更改后,解析器就完成了。在这种情况下,我的意思是:一种有效的页面解析方法,只要页面没有变化,它总是可以为我提供相同的结果(显然是针对同一组数据)。


8
没有稳定的方法,无论您以何种方式实施抓取,只要对网页进行简单的更改,就很容易破坏它。获取数据的稳定方法是与数据的作者联系并达成交易,以合理的方式获取数据。有时甚至不花钱。
约阿希姆·绍尔

1
@JoachimSauer-仍然可以使用“最佳”方法回答问题。
2012年

由于大多数网站是动态的,并将其数据存储在数据库中,所以最好的方法是从网站获取数据库。如果网站具有API,则可以使用它。如果您想抓取静态页面,则内置的Python urllib和HTMLParser模块可以很好地工作。PyPi还提供了一些用于抓取HTML的软件包。
Ubermensch 2012年

网站抓取是令人讨厌的事情。确实没有稳定的方法来执行此操作,因为网站所有者不希望您这样做,并且整个行业都在试图阻止人们这样做。
史蒂文·埃弗斯

1
也许嵌入Web浏览器(例如Webkit),然后使用DOM脚本从渲染的页面中获取信息?几乎每个平台都可以做到这一点,但是您可以在Qt中做到这一点:doc.qt.nokia.com/4.7-snapshot/qtwebkit-bridge.html
user16764 2012年

Answers:


2

好吧,这是我的2美分:

如果不涉及AJAX,或者很容易清除,则将HTML“修复”到XHTML(例如使用HTMLTidy),然后使用XPath而不是正则表达式来提取信息。
在结构良好的网页中,逻辑上分离的信息实体位于不同的<div>s或任何其他标记中,这意味着您可以使用简单的XPath表达式轻松找到正确的信息。这也非常好,因为您可以在Chrome的控制台或Firefox的开发人员控制台中对其进行测试,并在编写一行其他代码之前验证其是否正常工作。
这种方法还具有很高的信噪比,因为通常选择相关信息的表达式是单线的。它们也比正则表达式更易于阅读,并且是为此目的而设计的。

如果页面中包含AJAX和严肃的JavaScript,请在​​应用程序中嵌入浏览器组件,并使用其DOM触发所需的事件,并使用XPath提取信息。那里有很多很好的可嵌入浏览器组件,其中大多数都在幕后使用真实世界的浏览器,这是一件好事,因为网页可能是不正确的(X)HTML,但在所有主流浏览器上仍然表现出色(实际上,大多数页面最终都采用这种方式)。


谢谢,我一定会进一步介绍XPath。我不习惯使用它,所以这将是一件好事。+1 :)
Mike

5

以我的经验,在使用.NET环境时,您可以利用HTML Agility Pack

如果页面格式设置为XHTML,则还可以使用常规XML解析器。您可以想象的任何环境都有很多。

对于有关AJAX的附带问题,您可以使用常规的HTTP网络代码来获取数据并进行解析。

同样,如果您的AJAX堆栈返回XML,您将有很多选择。如果返回JSON,请考虑一个允许您将流映射到键入对象的库。在.NET中,我建议您使用Newtonsoft.Json


通过“ HTTP网络代码”,您的意思是捕获发出请求时服务器的响应?感谢您的建议,我一定会调查一下。+1
Mike

究竟。在.NET中,您可以使用System.Net.WebClient或RestSharp | restsharp.org。我也在Droid的Mono上使用了它。
gsscoder 2012年

4

解析HTML并不是一件容易的事,因为必须处理可能不正确的标记(标签汤)。多年来,浏览器已采用或多或少地采用相同的策略来处理错误,并且该算法已在HTML5规范中进行了命名(是的,HTML5规范指定了如何处理非HTML5的内容)。

是所有主要语言的库,用于解析HTML,例如this

无论如何,您得到的结果在任何意义上都是不稳定的。每次网页格式更改时,您都必须调整刮板。


谢谢,我一直在用Beautiful Soup来完成工作。我知道这将不稳定,我可能应该在我的问题中澄清这一点。+1 :)
Mike

4

附带提出一个问题:当通过Ajax调用构建网页时,您将如何处理?

如果正在进行ajax调用,则很有可能是带有某些变量的POST或GET URL。

我将检查JavaScript以找出端点和参数是什么。之后,很有可能返回的数据是json / xml / plain文本或部分html。

了解了以上信息后,您只需向该端点发出GET或POST请求,然后解析返回的数据。


2
值得一提的是,许多服务都会检查HTTP标头以确保HTTP_X_REQUESTED_WITHXMLHttpRequest。好的服务器还将为POST请求实现某种XSRF保护,因此您也将需要该魔术cookie。对某些公共API故意不公开的AJAX端点进行标记对我来说有点讨厌,并且如果输出(或请求策略)发生更改,则您的刮板也很容易损坏。
Tim Post

@TimPost您是100%正确的。我同意它的“恶心”的确:)但在没有任何公开的API,需要必须..
Darknight

我可以在我自己的AJAX驱动的应用程序上使用它(通过“拥有”,我并不是说我写了它,但是设置是我的),但是尝试绕过另一台服务器的系统感觉不对,所以我必须同意@ TimPost,感觉有点“刺耳”。这是个好主意,谢谢!+1!
Mike Mike

1

没有稳定或更好的方法来执行此操作,HTML网页不是要由计算机操纵的。它是针对人类用户的,但是如果您需要这样做,我建议您使用浏览器和一些JavaScript。在我的工作中,我参与了一个项目,该项目需要从第三方站点中提取一些信息。该应用程序是作为Chrome扩展程序开发的。页面加载完成后,将使用注入到网站上的JavaScript编写应用程序逻辑。提取的数据通过http服务器发送到数据库。这不是最好的方法,但是可以。附言:网站所有者已授权我们进行此类操作。


我知道HTML页面不应该由计算机解析,但有时根本没有其他选择。另外,我正在将公开信息用于个人项目,无论如何都不是商业用途,我认为我不需要明确的授权,对吗?感谢您的输入!也为您+1;)
迈克(Mike

@MikeHeremans要了解您是否有权从网站获取信息,请阅读ToS和robots.txt。如果两者都没有剥夺您自动删除信息的权利,那么在大多数情况下,您在法律上应该没问题。当然,IANAL ...
K.Steff

如果您想查看上述项目的代码,请访问:code.google.com/p/acao-toolkit/source/browse/…。检查content_script.js,它是插入到页面上的代码。
nohros 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.