这是为了提供一个规范的Q
我正在开发一个应用程序,需要解析一个网站中的表。由于导出用于抓取网页的XPath表达式是一项枯燥且容易出错的工作,我想为此使用Firebug的XPath提取器功能(或其他浏览器中的类似工具)。
示例输入如下所示:
<!-- snip -->
<table id="example">
<tr>
<th>Example Cell</th>
<th>Another one</th>
</tr>
<tr>
<td>foobar</td>
<td>42</td>
</tr>
</table>
<!-- snip -->
我想提取第一个数据单元(“foobar”)。Firebug提出了XPath表达式
//table[@id="example"]/tbody/tr[2]/td[1]
这在任何XPath测试插件中都可以正常工作,但在我自己的应用程序中却不行(没有找到结果)。如果我将查询缩减到//table[@id]
,它会再次工作。
出什么问题了?
只是遇到了同样的问题。我几乎编写了一个递归函数来检查每个tbody标记是否存在,并以这种方式遍历dom,然后我记得我知道regex:)
在解析之前,将html作为字符串获取。插入缺少的
延斯·埃拉特给出了一个很好的解释,但是这里是
JavaScript
var html = '<html><table><tr><td>foo</td><td>bar</td></tr></table></html>';
html.replace(/(<table([^>]+)?>([^<>]+)?)(?!<tbody([^>]+)?>)/g,"$1<tbody>").replace(/(<(?!(\/tbody))([^>]+)?>)(<\/table([^>]+)?>)/g,"$1</tbody>$4");
PHP
$html = $dom->saveHTML();
$html = preg_replace(array('/(<table([^>]+)?>([^<>]+)?)(?!<tbody([^>]+)?>)/','/(<(?!(\/tbody))([^>]+)?>)(<\/table([^>]+)?>)/'),array('$1<tbody>','$1</tbody>$4'),$html);
$dom->loadHTML($html);
只有正则表达式:
matches `<table>` tag with whatever else junk inside the tag and between this and the next tag if the next tag is NOT `<tbody>` also with stuff inside the tag
/(<table([^>]+)?>([^<>]+)?)(?!<tbody([^>]+)?>)/
replace with
$1<tbody>
the $1 referencing the captured `<table>` tag with contents.
Do the same for the closing tag like this:
/(<(?!(\/tbody))([^>]+)?>)(<\/table([^>]+)?>)/
replace with
$1</tbody>$4
这样,dom将始终具有
Firebug是Chrome的开发工具,JavaScript中的XPath函数和其他函数在DOM上工作,而不是基本的HTML源代码。
超文本标记语言的DOM要求所有表行不包含在页脚(
tbody
元素对于所有表都是公开的,即使该表没有明确定义tbody
元素。
关于stackoverflow的另一个答案中有一个深入的解释。
另一方面,超文本标记语言不一定需要使用该标记:
除非桌子只包含一个桌子主体且没有桌子头或脚部分,否则始终需要
t桌子主体
开始标签。
除了JavaScript之外,大多数XPath处理器都处理原始XML,而不是DOM,因此不会添加
这是在Stackoverflow上发布的PHP、Ruby、Python、Java、C#、GoogleDocs(电子表格)和其他许多应用程序的常见问题。Selenium在浏览器内部运行,在DOM上工作——因此它不受影响!
将Firebug(或Chrome的开发工具)显示的源代码与通过右键单击并选择“显示页面源代码”(或浏览器中的任何名称)或使用
curl获得的源代码进行比较http://your.example.org
在命令行上。后者可能不包含任何
检查你卡住的表是否真的不包含
现在删除
/tbody
轴步骤,这样您的查询将看起来像
//table[@id="example"]/tr[2]/td[1]
这是一个相当脏的解决方案,对于嵌套表可能会失败(可以跳转到内部表)。我只会在非常罕见的情况下建议这样做。
将
/tbody
轴步骤替换为后代步骤或自身步骤:
//table[@id="example"]//tr[2]/td[1]
如果您事先不确定您的表或查询是否同时在“HTML源代码”和DOM上下文中使用;并且不想/不能使用解决方案2中的hack,提供一个替代查询(针对XPath 1.0)或使用“可选”axis步骤(XPath 2.0及更高版本)。
XPath 1.0:
//表[@id=“example”]/tr[2]/td[1]|//表[@id=“example”]/tbody/tr[2]/td[1]
- XPath 2.0:
//表[@id=“example”]/(tbody,)/tr[2]/td[1]
问题内容: 这旨在对每周出现一次或两次的所有类似问题(但过于具体的问题,不能成为接近的目标候选人)提供规范的问答。 我正在开发一个应用程序,该应用程序需要解析带有表的网站。由于派生用于抓取网页的XPath表达式很无聊且容易出错,因此我想为此使用 Firebug 的XPath提取器功能 (或其他浏览器中的类似工具)。 输入示例如下所示: 我想提取第一个数据单元格(“ foobar”)。Firebug
我想知道为什么我的Java程序在控制台工作,当我做: javac Main.java Java美因河 ...而不是在Eclipse中,因为我有这个错误: 线程“main”java.lang.NullPointerException在codepin.main.main(main.java:48)-->char passwordarray[]=console.readpassword(“enter p
在我的项目中,电影和演员、电影和类别之间有着多对多的关系。当我尝试创建一部电影,然后尝试使用Select2添加演员和类别时,它不会列出可用的选项(输入字段看起来是灰色的,好像它们被锁定了)。我查看脚本是否正在加载,它们是否正在加载。这是我的密码。
问题是,我试图使用findViewById()全局初始化TextView对象,但它在运行时抛出一个错误,然后,如果我在onCreate()或任何其他方法中使用它,初始化工作就会很好。 我正在为API级别22及以上开发
我有一个主活动MainActivity,它是我的android应用程序的入口点。它通过发射器正确发射。然而,当我尝试执行startActivity时,我看到活动试图启动的一些调试,一些代码正确启动,但MainActivity从未启动。 我认为这可能与意图有关: 对吗? 从内部活动来看,我有 我甚至看到 10-11 22:23:46.026:INFO/ActivityManager(472):从pi
我试图隐藏Actionbar并改用工具栏,但如果我更改Theme.appcompat.light.NoActionBar,它确实会隐藏,但应用程序在行setContentView(r.layout.activity_main)处崩溃; 尽管它确实使用getSupportActionBar()隐藏。hide();但我不能用这个代码 Toolbar Toolbar=(Toolbar)findViewB