Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用lxml html从嵌套元素中提取特定元素_Python_Html_Parsing_Xpath_Lxml - Fatal编程技术网

Python 使用lxml html从嵌套元素中提取特定元素

Python 使用lxml html从嵌套元素中提取特定元素,python,html,parsing,xpath,lxml,Python,Html,Parsing,Xpath,Lxml,大家好,我有一些问题,我认为可以归因于xpath问题。我正在使用lxml包中的html模块尝试获取一些数据。我在下面提供了最简单的情况,但请记住,我使用的html要难看得多 <table> <tr> <td> <table> <tr><td></td></tr> <tr><td>

大家好,我有一些问题,我认为可以归因于xpath问题。我正在使用lxml包中的html模块尝试获取一些数据。我在下面提供了最简单的情况,但请记住,我使用的html要难看得多

<table>
    <tr>
    <td>
        <table>
            <tr><td></td></tr>
            <tr><td>
                <table>
                    <tr><td><u><b>Header1</b></u></td></tr> 
                    <tr><td>Data</td></tr>
                </table>
            </td></tr>
        </table>
     </td></tr>
</table>
但这给了我所有的表元素。我只想要一个包含此文本的表。我知道发生了什么,但除了爆发一些讨厌的正则表达式外,我很难想出如何做到这一点。
有什么想法吗

也许这对你有用:

tree.xpath("//table[not(descendant::table)]/*[contains(., 'Header1')]")
not(后代::表)
位确保获得最内层的表

table, = tree.xpath('//*[.="Header1"]/ancestor::table[1]')
  • /*[text()=“Header1”]
    使用文本
    Header1
    选择文档中任意位置的元素
  • 祖先::表[1]
    选择元素的第一个祖先,即
完整示例
#/usr/bin/env python
从lxml导入html
第“”页
校长1
资料
"""
tree=html.fromstring(第页)
表,=tree.xpath('/*[.=“Header1”]/祖先::表[1]')
打印html.tostring(表)

找到您感兴趣的标题,然后拉出其表格

//u[b = 'Header1']/ancestor::table[1] 并期望内部谓词(
/*…
)神奇地从正确的上下文开始。使用
/
从上下文节点开始。即使如此,这:

//table[.//*[contains(text(), "Header1")]] //表[./*[包含(text(),“Header1”)]] 因为即使是最外层的表也包含深层的文本
'Header1'
,所以谓词对示例中的每个表的计算结果都是true。像我那样使用
not()
,确保没有嵌套其他表

另外,不要在每个节点上测试该条件,因为它不可能在每个节点上都是真的。更有效的方法是具体化。

使用:

//td[text() = 'Header1']/ancestor::table[1]

虽然这个例子是正确的,但我认为使用
/*[.=“Header1”]
太通用了。输入中可能有一个
see Header1
,您的表达式将与
@Tomalak匹配:它总是匹配
元素。什么元素包含
“Header1”
并不重要,只要它在
元素中的某个地方就行了。对,这里没有参数。尽管如此,我的观点是,您可能没有匹配表头本身,但是任何偶然包含文本
'Header1'
的泛型内容。很可能您匹配了错误的表。@DerrickPetzold:有关良好的XPath/XSLT资源,请参阅以下答案:@DimitreNovatchev您所指的答案已被删除: //td[not(.//table) and .//b = 'Header1']/ancestor::table[1] //table[//*[contains(text(), "Header1")]] //table[.//*[contains(text(), "Header1")]]
//td[text() = 'Header1']/ancestor::table[1]