【发布时间】:2013-08-24 04:40:47
【问题描述】:
我遇到了一个看起来非常简单的问题。我正在尝试通过 Xpath 导航到 HTML 中的元素,但似乎无法使其正常运行。
我想从页面的 html 内容中获取一个跨度。该页面相当复杂,因此我一直在使用 Firebug 的“通过 xpath 获取元素”并将结果粘贴到我的代码中。我注意到它与您在 Chrome 中执行相同操作所获得的 xpath 略有不同,但它们似乎都指向同一个地方。
我要导航的 html 是 found here。我试图通过 xpath 访问的字段是第一个“n 的结果 1 - 10”。
基于 FireBug 的“检查元素”,xpath 应为:/html/body/div/center/table/tbody/tr[6]/td/table/tbody/tr/td[2]/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/span
但是,当我尝试使用此 xpath 来识别 C# 代码隐藏中的元素时,它给了我一些错误,无法找到该路径。
我在这里做错了吗?我已经尝试了 xpath 的许多排列,但我不明白为什么这不会在代码中进行协作。
编辑:我在 HTMLAgilityPack 中遇到了这个问题(但设法改用正则表达式破解了一个糟糕的解决方案)和一个以答案 found here 为模型的 SELECT 语句
编辑 2:我正在尝试使用 Yahoo 的免费代理解决此问题,如示例 here 所示:
var query = 'SELECT * FROM html WHERE url="http://mattgemmell.com/2008/12/08/what-have-you-tried/" and xpath="//h1" and class="entry-title"';
var url = "http://query.yahooapis.com/v1/public/yql?q=" + query + "&format=json&callback=??";
$.getJSON(url,function(data){
alert(data.query.results.h1.content);
})
我在使用 HTML 敏捷包时遇到了同样的问题,但我更感兴趣的是让这部分工作。它适用于回答者给我的提供的 URL(见上文)。但是,当我尝试在 http://nl.newsbank.com url 上使用简单的 xpath 表达式时,我会收到错误,即每次都没有检索到任何对象,无论 xpath 多么基本。
编辑 3:我想我会更详细地阐述我正在尝试解决的更大问题的大图,这个问题是一个关键组成部分,希望它可能提供更多的洞察力。
为了从头开始学习基本的 ASP.NET 开发技能,我决定基于 http://nl.newsbank.com/ 的新闻存档搜索创建一个简单的 Web 应用程序。在当前的迭代中,它发送一个 POST 请求(尽管我现在了解到您可以使用 GET 请求并将正文转储到 URL 的末尾)来发送搜索条件,就好像用户在搜索栏中输入了条件一样.然后它在响应中搜索“n 的结果 1-n”跨度(使用 RegExes,而不是 Xpath,因为我无法正常工作),提取 n,并将其转储到表中。这是一个很酷的小工具,可用于查找一段时间内的新闻发生率。
我想添加一些功能,以便您可以输入一个日期范围(例如 2002 年 5 月 - 2010 年 6 月)并在该范围内的每个月/周运行频率搜索。这在概念上很容易实现。然而问题是,现在这一切都发生在服务器端,并且由于没有 API,HTTP 响应包含整个页面,因此非常占用带宽。一次发送几十个查询会占用绝对难以形容的带宽,甚至没有一点可扩展性。
因此,我尝试重写应用程序以在客户端工作。但是由于same-origin policy,我无法从客户端向外部主机发送请求。但是有一个漏洞,我可以使用免费的 Yahoo 代理发出请求并将其转换为 JSON,然后我可以使用同源策略的 JSON 异常从代理中检索该数据。
这就是我遇到http://nl.newsbank.com 特有的这些 xpath 问题的地方。我无法使用任何 xpath 检索 html,而且我不确定为什么或如何修复它。在VS2010调试时,我会收到错误Microsoft JScript runtime error: Unable to get value of the property 'content': object is null or undefined
【问题讨论】:
-
页面有多个 IFrame。根据您使用的技术,它可能需要一点“推动”来处理 IFrame。你用的是什么技术? LINQ2XML? HtmlAgilityPack?硒?瓦廷?
-
HtmlAgilityPack 和一个 SELECT 语句都以编辑中的链接答案为模型(我并不复杂地理解代码,但似乎在示例中有效)
-
尝试删除表达式中的
tbody元素。tbody元素通常由 Firefox 或 Chrome 添加,前提是它们没有出现在源 HTML 中tr之前。所以像/html/body/div/center/table/tr[6]/td/table/tr/td[2]/table/tr/td/table/tr/td/table/tr/td/table/tr/td/span这样的东西可能会起作用。或者更安全/html/body/div/center/table//tr[6]/td/table//tr/td[2]/table//tr/td/table//tr/td/table//tr/td/table//tr/td/span -
谢谢,我试试看。
-
关于 Html Agility Pack:在线上的 HTML(库通常使用的那个)和浏览器的内存 DOM 之间可能存在巨大差异,因为第二个可能是完全由客户端javascript创建。否则,恕我直言,您不应该像您展示的那样使用 XPATH(这 不是 简单的 XPATH),这是厄运的秘诀。 HTML 上的 XPATH 表达式应针对唯一的最小判别元素进行定制。调试工具提供的 XPATH 几乎无法使用。您应该改用 thinks lile
//td[@class='blabla']或//span[@id='blabla'。