Sup*_*Spy 1 php xpath screen-scraping
编辑:我添加了一个适用于这种情况的解决方案.
我想从页面中提取一个表,我想(可能)使用DOMDocument和XPath.但如果你有更好的主意,请告诉我.
我的第一次尝试就是这个(显然是错误的,因为它将获得第一个关闭表标签):
<?php
$tableStart = strpos($source, '<table class="schedule"');
$tableEnd = strpos($source, '</table>', $tableStart);
$rawTable = substr($source, $tableStart, ($tableEnd - $tableStart));
?>
Run Code Online (Sandbox Code Playgroud)
我很难,这可能是用DOMDocument和/或xpath解决的......
最后,我希望标签之间的所有内容(在本例中为标签)和标签自身.所以所有HTML,不仅仅是值(例如,不只是'价值',而是'价值').并且有一个"捕获"......
这可能吗?
这是我想要从另一个网站提取的(简化的)源代码:(我还想显示html标签,而不仅仅是值,所以整个表格都带有'schedule'类)
<table class="schedule">
<table class="annoying nested table">
Lots of table rows, etc.
</table> <-- The problematic tag...
<table class="annoying nested table">
Lots of table rows, etc.
</table> <-- The problematic tag...
<table class="annoying nested table">
Lots of table rows, etc.
</table> <-- a problematic tag...
This could even be variable content. =O =S
</table>
Run Code Online (Sandbox Code Playgroud)
首先,请注意XPath基于XML Infopath - 一种XML模型,其中没有"起始标记"和"结束标记",只有节点
因此,不应期望XPath表达式选择"标签" - 它选择节点.
考虑到这一事实,我将这个问题解释为:
我想获得给定的"start"元素和给定的"end元素"之间的所有元素的集合,包括start和end元素.
在XPath 2.0中,这可以通过标准运算符交叉方便地完成.
在XPath 1.0(我假设您正在使用)中,这并不容易.解决方案是使用Kayessian(由@Michael Kay)公式进行节点集交集:
两个节点集合的交集:$ns1和$ns2通过评估以下XPath表达式选自:
$ns1[count(.|$ns2) = count($ns2)]
Run Code Online (Sandbox Code Playgroud)
假设我们有以下XML文档(因为您从未提供过):
<html>
<body>
<table>
<tr valign="top">
<td>
<table class="target">
<tr>
<td>Other Node</td>
<td>Other Node</td>
<td>Starting Node</td>
<td>Inner Node</td>
<td>Inner Node</td>
<td>Inner Node</td>
<td>Ending Node</td>
<td>Other Node</td>
<td>Other Node</td>
<td>Other Node</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
start元素通过以下方式选择:
//table[@class = 'target']
//td[. = 'Starting Node']
Run Code Online (Sandbox Code Playgroud)
结束元素选择:
//table[@class = 'target']
//td[. = Ending Node']
Run Code Online (Sandbox Code Playgroud)
为了获得所有想要的节点,我们将以下两组相交:
该组由start元素和所有后续元素组成(我们将其命名为$vFollowing).
由end元素和所有前面的元素组成的集合(我们将其命名为$vPreceding).
它们分别由以下XPath表达式选择:
$ vFollowing:
$vStartNode | $vStartNode/following::*
Run Code Online (Sandbox Code Playgroud)
$ vPreceding:
$vEndNode | $vEndNode/preceding::*
Run Code Online (Sandbox Code Playgroud)
现在我们可以简单地在节点集上应用Kayessian公式,$vFollowing并且$vPreceding:
$vFollowing
[count(.|$vPreceding)
=
count($vPreceding)
]
Run Code Online (Sandbox Code Playgroud)
剩下的就是用各自的表达式替换所有变量.
基于XSLT的验证:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vStartNode" select=
"//table[@class = 'target']//td[. = 'Starting Node']"/>
<xsl:variable name="vEndNode" select=
"//table[@class = 'target']//td[. = 'Ending Node']"/>
<xsl:variable name="vFollowing" select=
"$vStartNode | $vStartNode/following::*"/>
<xsl:variable name="vPreceding" select=
"$vEndNode | $vEndNode/preceding::*"/>
<xsl:template match="/">
<xsl:copy-of select=
"$vFollowing
[count(.|$vPreceding)
=
count($vPreceding)
]"/>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当应用于上面的XML文档时,将评估XPath表达式并输出所需的,正确的结果选择节点集:
<td>Starting Node</td>
<td>Inner Node</td>
<td>Inner Node</td>
<td>Inner Node</td>
<td>Ending Node</td>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4958 次 |
| 最近记录: |