1

我有这个 html 片段:

<tr>
    <th scope="row" style="text-align:left;">Appeared in</th>
    <td class="" style="">1972<sup id="cite_ref-dottcl_2_2-0" class="reference"><a href="#cite_note-dottcl_2-2"><span>[</span>2<span>]</span></a></sup></td>
</tr>
<tr>
    <th scope="row" style="text-align:left;">Usual 
<a href="/wiki/Filename_extension" title="Filename extension">filename extensions</a>
    </th>
    <td class="" style="">.h .c</td>

</tr>

我正在使用//th//text()表达式来解析它。

问题是它正在返回['Appeared in', 'Usual', 'filename extensions']

我想要的是['Appeared in', 'Usual filename extensions']

4

2 回答 2

2

您需要 XPath 2.0 来执行此操作,这些脚本语言(包括 scrapy)的大多数 XML 库都不支持。

如果您可以使用功能更强大的 XPath 处理器(还可以查看 XQuery 1.0 和更新版本,它们都至少包含 XPath 2.0 作为子集),请使用:

//th/data()

/data()等效于/data(.)为当前上下文调用函数。

data()对比text()

虽然text()不是函数调用,但节点过滤器(因此//text()是将所有文本节点单独添加到结果序列的轴步骤)data()是聚合当前上下文的所有数据的函数(此处:每个<th/>单独)。

XPath 1.0 限制

无法调用任何单独连接每个表头元素的字符串的函数:不支持轴步骤中的函数调用,也不支持像在 XPath 2.0 中那样的显式循环。

于 2013-06-02T19:17:40.883 回答
0

啊,我会因为使用解析 HTML 而被否决,但无能为力:

$html = '<tr>
    <th scope="row" style="text-align:left;">Appeared in</th>
    <td class="" style="">1972<sup id="cite_ref-dottcl_2_2-0" class="reference"><a href="#cite_note-dottcl_2-2"><span>[</span>2<span>]</span></a></sup></td>
</tr>
<tr>
    <th scope="row" style="text-align:left;">Usual 
<a href="/wiki/Filename_extension" title="Filename extension">filename extensions</a>
    </th>
    <td class="" style="">.h .c</td>

</tr>';

$html = str_replace("\r", '', str_replace("\n", '', $html)); // Remove new lines
preg_match_all('#<th[^>]*>(.*?)</th>#is', $html, $m); // Match what's between th tag

$result = array_map('strip_tags', $m[1]); // Get ride of html tags
print_r($result);// printing the results

输出:

Array
(
    [0] => Appeared in
    [1] => Usual filename extensions    
)
于 2013-06-02T18:49:49.383 回答