如何智能地解析搜索结果在页面上返回的数据?
例如,假设我想通过解析许多图书提供商网站的搜索结果来创建一个搜索在线图书的网络服务。我可以获取页面的原始HTML数据,并做一些正则表达式以使数据适用于我的Web服务,但如果任何网站更改了页面的格式,我的代码就会中断!
RSS确实是一个了不起的选择,但许多网站没有基于XML / JSON的搜索。
是否有任何套件可以帮助自动在页面上传播信息?一个疯狂的想法是让模糊的AI模块识别搜索结果页面上的模式,并相应地解析结果......
答案 0 :(得分:24)
我最近做了一些,这是我的经历。
有三种基本方法:
我在选项2中使用web harvest进行了修改,但我发现它们的语法有点奇怪。混合使用XML和一些伪Java脚本语言。如果您喜欢Java,并且喜欢XML风格的数据提取(XPath,XQuery),它可能是您的门票。
编辑:如果您使用正则表达式,请确保使用具有延迟量词和捕获组的库! PHP的旧正则表达式库缺少这些,它们对于在HTML中打开/关闭标记之间的数据匹配是必不可少的。
答案 1 :(得分:3)
如果没有修复 HTML结构进行解析,我不愿意维护正则表达式来查找数据。您可能更幸运通过构建树的适当解析器来解析HTML。然后选择那些更易于维护的元素。
显然,最好的方法是引擎的一些XML输出,带有可以解析和验证的固定标记。我认为,对于生成的树进行一些“黑暗”探测的HTML解析库比正则表达式更容易维护。
这样,您只需检查<a href="blah" class="cache_link">...
转入<a href="blah" class="cache_result">...
或其他任何内容。
最重要的是,使用正则表达式来渲染特定元素将是严峻的。一种更好的方法是构建一个类似于页面模型的DOM,并查找标签中字符数据的“锚点”。
或向该网站发送电子邮件,说明XML API案例......您可能会被录用!
答案 2 :(得分:3)
您没有说出您正在使用的语言。在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);
我建议外部化XPath表达式,以便在站点更改时有一定程度的保护。
这是一个示例XPath,我绝对不会用来截屏这个网站。没办法,不是我:
"//h:div[contains(@class,'question-summary')]/h:div[@class='summary']//h:h3"
答案 3 :(得分:2)
您尚未提及您正在使用的技术堆栈。如果你正在解析HTML,我会使用一个解析库:
还有一些网络服务正是您所说的 - 商业和免费。他们抓住网站并提供网络服务接口。
提供一些屏幕抓取的通用网络服务是Yahoo Pipes。 previous stackoverflow question on that
答案 4 :(得分:2)
这不是万无一失但你可能想要查看一个解析器,例如Beautiful Soup如果布局发生变化,它不会神奇地找到相同的信息,但它比编写复杂的正则表达式要容易得多。注意这是一个python模块。
答案 5 :(得分:1)
您是否考虑过使用html操作库? Ruby有一些非常好的。例如hpricot
使用好的库,您可以使用CSS选择器或xpath指定所需页面的各个部分。这些比使用正则表达式更强大。
来自hpricot wiki的示例:
doc = Hpricot(open("qwantz.html"))
(doc/'div img[@src^="http://www.qwantz.com/comics/"]')
#=> Elements[...]
我相信你可以找到一个在.NET或Python等中做类似事情的库。
答案 6 :(得分:1)
不幸的是,'抓取'是最常见的解决方案,正如您所说的尝试从网站解析HTML。您可以检测到页面的结构更改并标记要修复的警报,因此更改结果不会导致bum数据。在语义网成为现实之前,这几乎是保证大型数据集的唯一方法。
或者,您可以坚持使用API提供的小型数据集。雅虎正在努力通过API提供可搜索的数据(参见YDN),我认为亚马逊API开辟了大量的书籍数据等。
希望有所帮助!
编辑:如果您使用的是PHP,我建议使用SimpleHTMLDOM
答案 7 :(得分:1)
尝试使用Google搜索屏幕抓取+您喜欢的语言。 我知道python的几个选项,你可能会找到相应的首选语言:
根据要抓取的网站,您可能需要使用上述一种或多种方法。
答案 8 :(得分:0)
如果您可以使用类似Tag Soup的内容,那就是一个可以开始的地方。然后,您可以将页面视为XML API,有点。
它有Java和C ++实现,可能有效!
答案 9 :(得分:0)
http://www.parselets.com的欧芹看起来很漂亮。
它允许您使用JSON定义'parslets',您可以在页面上定义要查找的内容,然后为您解析该数据。
答案 10 :(得分:0)
正如其他人所说,您可以使用构建DOM表示的HTML解析器并使用XPath / XQuery进行查询。我在这里发现了一篇非常有趣的文章:Java理论与实践:使用XQuery进行屏幕抓取 - http://www.ibm.com/developerworks/xml/library/j-jtp03225.html
答案 11 :(得分:-2)
很公平,我将按照推荐使用Tag汤方法。
作为一个后续问题 - 这些大型刮刀型网站究竟是如何做到的?我见过一个可以扫描数千个网站的求职搜索引擎(例如Indeed.com)!是成千上万的正则表达式?它几乎不可能......