如何使用xpath排除某些元素?

时间:2014-11-09 22:21:13

标签: python html xpath web-scraping scrapy

所以我正在开发一个Scrapy项目,并且我已经使用XPath获取了以下一些HTML:

<table id='foobar'>
    <tr>
        <td><p>....</td>
        <td><div>...</div></td>
    </tr>
    <tr>
        <td><script type='text/javascript'>...</script></td>
        <td><p>.....<br></td>
    </tr>
    <tr>
        <td><div><p>.....</div></td>
        <td><script type='text/javascript'>...</script></td>
    </tr>
    <!--repeat for another 250 or so rows-->
</table>

这是<div><p>中的表格数据的混合,其中包含一堆脚本标记。有时<script>标记位于<div>内,这使得这更复杂一些。基本上我需要的是WHOLE表,但不是脚本标签或其内容。 XPath最初是:

//table[contains(@id, 'foobar')]

但这并不排除脚本标记,因此我将其更改为

//table[contains(@id, 'foobar')]//script/*[following-sibling::* and preceding-sibling::*]
认为这会奏效,但是。这可以在xpath中完成吗?或者我只是从表中抓取所有内容,迭代内容,并删除其中包含“text / javascript”的内容?

1 个答案:

答案 0 :(得分:1)

使用//*[not(self::script)]可以排除<script>代码

的所有子节点
from lxml import etree

# you have invalid closing tags which I have fixed on my string
s = '''
<table id='foobar'>
    <tr>
        <td><p>....</p></td>
        <td><div>...</div></td>
    </tr>
    <tr>
        <td><script type='text/javascript'>...</script></td>
        <td><p>.....<br /></p></td>
    </tr>
    <tr>
        <td><div><p>.....</p></div></td>
        <td><script type='text/javascript'>...</script></td>
    </tr>
    <!--repeat for another 250 or so rows-->
</table>
'''

tree = etree.fromstring(s)

for each in tree.xpath("//table[contains(@id, 'foobar')]//*[not(self::script)]"):
    print each.tag

tr
td
p
td
div
tr
td
td
p
br
tr
td
div
p
td