【问题标题】:Why the two trs were parsed as just the same first tr by lxml?为什么两个 tr 被 lxml 解析为相同的第一个 tr?
【发布时间】:2019-08-09 03:02:01
【问题描述】:

我为target_html画了简单的结构:

table--div--tr[id="tr1"]
     |--tr[id="tr2"]
     |--tr[id="tr3"]
     |--tr[id="tr4"]

使用 lxml 从 target_html 中提取第一个 tr。

target_html="""
<table id="t1"> 
<div id="div1"> 
<tr id="tr1"> 
<td>11</td> 
<td>12</td> 
</tr> 
</div> 

<tr id="tr2">
<td>21</td> 
<td>22</td> 
</tr>

<tr id="tr3"> 
<td>31</td> 
<td>32</td> 
</tr> 

<tr id="tr4"> 
<td>41</td> 
<td>42</td> 
</tr> 
</table> """

doc=lxml.html.fromstring(target_html)
for item in doc.xpath('//tr[1]'):
    print(item.text_content())

lxml解析的扩展结果:

11 
12 

lxml解析出来的真实结果:

11 
12     

21 
22 

为什么两个 tr 被解析为tr[1]

【问题讨论】:

  • // 为所有出现的tr[1] 做一个通配符。根据您的示例,//div/tr[1] 将产生您预期的结果。
  • 我相信这是因为//tr[1] 的意思是“任何时候在同一级别有一个或多个tr,选择第一个。” tr1 在一个 div 的下面,所以它和其他三个不在同一个级别,所以它被选中了。 tr2 也被选中,因为它是同一级别的三个中的第一个。

标签: python html-parsing lxml


【解决方案1】:

xpath //tr[1] 表示选择任何tr 元素,它是其父元素的第一个子元素(具有该名称)。

选择以下tr,因为它是div 的第一个tr 子代:

<tr id="tr1"> 
<td>11</td> 
<td>12</td> 
</tr>

选择以下tr,因为它是table 的第一个tr 子代:

<tr id="tr2">
<td>21</td> 
<td>22</td> 
</tr>

要获取第一个匹配项,首先将 xpath 括在括号中...

doc.xpath('(//tr)[1]')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-31
    • 2021-12-20
    • 2016-12-26
    • 2013-08-25
    • 2010-11-06
    • 2016-09-05
    • 2020-05-27
    • 2011-07-08
    相关资源
    最近更新 更多