首页 > 解决方案 >
仅使用 Xpath 提取标签内部分文本的文本

问题描述

我只想从这里抓取字符串:

                  <br>

                5 Brown Circle<br>

                Alabaster,

                AL &nbsp;&nbsp;

                35007

我需要深入了解如何从 html doc 之后的上述部分中提取文本:

<tr class="prem-tr" id="10425" role="row">
                    <td>
                        <h4><a class="prem-result-link" href="/Search/Details/10425">Graham &amp; Associates, CPAs</a></h4>

                        <a href="tel:+(205) 663-6673">(205) 663-6673</a>
                        <br>

                        5 Brown Circle<br>

                        Alabaster,

                        AL &nbsp;&nbsp;

                        35007

                        <div class="row result-btmRow">
                            <div class="col-sm-4">
                                <span class="result-dist"><small>Distance: 0.00 miles</small></span>
                            </div><!-- col6 -->
                            <div class="col-sm-8 result-actions">
                                <a id="WebsiteURL" class="visit-site" href="http://grahamandassociates.net" target="_blank">Visit Website</a>&nbsp;&nbsp;

                                <a class="send-email" href="/Search/Details/10425">Send a Message</a>
                            </div><!-- /col6 -->
                        </div><!-- /row -->
                    </td>
                </tr>

预期输出:5 Brown Circle, Alabaster, AL 35007仅使用 xpath 和解释。

或者

在 css 选择器中,它工作正常。谁能解释下面的代码?谢谢

" ".join([" ".join(el.root.strip().split()) for el in sel.css("td::text") if el.root.strip()])

标签: pythonxpath

解决方案


我不会说这是一个很好的解决方案,但如果要求只使用 XPath 1.0...

normalize-space(translate(concat(//td/text()[4], //td/text()[5]),"\xa0", ""))

稍微分解一下并在 iPython 中演示lxml.etree

td可以使用 选择作为 的子级的所有文本节点//td/text()。这不包括姓名和电话号码,因为它们是后代而不是孩子。

In [73]: root.xpath('//td/text()')
Out[73]: 
['\n                        ',
 '\n\n                        ',
 '\n                        ',
 '\n\n                        5 Brown Circle',
 '\n\n                        Alabaster,\n\n                        AL \xa0\xa0\n\n                        35007\n\n                        ',
 '\n                    ']

理想情况下,我们可以连接所有这些字符串并用 规范化空格normalize-space(),但这很尴尬,因为在 XPath 1.0 中,我们只有concat()可用的,它只需要两个参数。在 Python 中处理这个问题join()会更好,但是因为我们感兴趣的只有两个文本节点,所以我们可以使用concat()来连接集合中的第四个和第五个文本节点,以获得纯 XPath 解决方案。

In [74]: root.xpath('concat(//td/text()[4], //td/text()[5])')
Out[74]: '\n\n                        5 Brown Circle\n\n                        Alabaster,\n\n                        AL \xa0\xa0\n\n                        35007\n\n                        '

现在我们可以申请normalize-space()清理空白了。


In [75]: root.xpath('normalize-space(concat(//td/text()[4], //td/text()[5]))')
Out[75]: '5 Brown Circle Alabaster, AL \xa0\xa0 35007'              '

差不多好了。translate()现在我们只需要在规范化空间之前去掉不间断的空格字符。

In [79]: root.xpath('normalize-space(translate(concat(//td/text()[4], //td/text()[5]),"\xa0", ""))')
Out[79]: '5 Brown Circle Alabaster, AL 35007'

请注意,因为这是 Python,我们必须使用\xa0代替&nbsp;&#160;来表示不间断空格字符。


推荐阅读