如何智能解析网页搜索结果返回的数据?
举个例子,假设我想创建一个网络服务,通过解析多个图书供应商网站的搜索结果来查找在线书籍。我可以获取页面的原始HTML数据,并进行一些正则表达式操作,使数据适用于我的网络服务,但如果任何一个网站更改了页面的格式,我的代码就会出现错误!
RSS确实是一个很好的选择,但许多网站没有基于XML/JSON的搜索。
是否有任何工具包可以帮助自动传播页面上的信息?一个疯狂的想法是使用模糊AI模块识别搜索结果页面上的模式,并相应地解析结果...
如何智能解析网页搜索结果返回的数据?
举个例子,假设我想创建一个网络服务,通过解析多个图书供应商网站的搜索结果来查找在线书籍。我可以获取页面的原始HTML数据,并进行一些正则表达式操作,使数据适用于我的网络服务,但如果任何一个网站更改了页面的格式,我的代码就会出现错误!
RSS确实是一个很好的选择,但许多网站没有基于XML/JSON的搜索。
是否有任何工具包可以帮助自动传播页面上的信息?一个疯狂的想法是使用模糊AI模块识别搜索结果页面上的模式,并相应地解析结果...
我最近进行了一些工作,以下是我的经验。
有三种基本方法:
我尝试过使用Web Harvest来进行第二个选项的操作,但我觉得他们的语法有点奇怪。这是一种混合了XML和一些伪Java脚本语言的方式。如果您喜欢Java,并且喜欢XML风格的数据提取(XPath,XQuery),那么这可能适合您。
编辑:如果使用正则表达式,请确保使用具有惰性量词和捕获组的库!PHP较旧的正则表达式库缺少这些内容,而它们对于在HTML的开放/关闭标记之间匹配数据至关重要。
您没有说明使用的编程语言。在Java领域,您可以使用TagSoup和XPath来帮助最小化痛苦。这里有一个来自this blog的示例(当然,随着您的需求变得更加复杂,XPath可能会变得更加复杂):
URL url = new URL("http://example.com");
SAXBuilder builder = new SAXBuilder("org.ccil.cowan.tagsoup.Parser"); // build a JDOM tree from a SAX stream provided by tagsoup
Document doc = builder.build(url);
JDOMXPath titlePath = new JDOMXPath("/h:html/h:head/h:title");
titlePath.addNamespace("h","http://www.w3.org/1999/xhtml");
String title = ((Element)titlePath.selectSingleNode(doc)).getText();
System.out.println("Title is "+title);
"//h:div[contains(@class,'question-summary')]/h:div[@class='summary']//h:h3"
<a href="blah" class="cache_link">...
变成<a href="blah" class="cache_result">...
或其他什么。虽然不是百分之百可靠,但你可以考虑使用解析器,例如Beautiful Soup。如果页面布局发生变化,它不会神奇地找到相同的信息,但比编写复杂的正则表达式容易得多。请注意,这是一个Python模块。
您考虑过使用 HTML 操作库吗?Ruby 有一些非常不错的库,例如 hpricot。
如果使用好的库,您可以使用 CSS 选择器或 XPath 指定页面上需要的部分。这比使用正则表达式更加健壮可靠。
下面是 hpricot wiki 上的示例:
doc = Hpricot(open("qwantz.html"))
(doc/'div img[@src^="http://www.qwantz.com/comics/"]')
#=> Elements[...]
我相信你可以在 .NET 或 Python 等编程语言中找到一个能够实现类似功能的库。
不幸的是,“爬取”是最常见的解决方案,就像你所说的尝试从网站解析HTML。您可以检测页面的结构更改并标记警报以供您修复,因此他们端口的更改不会导致错误数据。在语义网络成为现实之前,这几乎是确保大型数据集的唯一方法。
或者,您可以坚持使用API提供的小型数据集。雅虎正在努力通过API提供可搜索的数据(请参阅YDN),我认为Amazon API开放了很多书籍数据等等。
希望这有点帮助!
编辑:如果您使用PHP,我建议使用SimpleHTMLDOM。
尝试谷歌搜索屏幕抓取+您喜欢的编程语言。 我知道一些Python选项,您可能会找到您喜欢的编程语言的等效选项:
根据要抓取的网站,您可能需要使用上述一种或多种方法。
http://www.parselets.com 上的 Parsley 看起来相当不错。
它允许你使用 JSON 定义“parslets”,从而定义在页面上搜索什么内容,然后将这些数据解析出来。
正如其他人所说,您可以使用构建DOM表示并使用XPath/XQuery进行查询的HTML解析器。我在这里找到了一篇非常有趣的文章:Java理论与实践:使用XQuery进行屏幕抓取-http://www.ibm.com/developerworks/xml/library/j-jtp03225.html