使用条件选择xPath子选择

时间:2018-05-04 18:05:46

标签: python xpath lxml

此刻我一直在努力处理一些xPath操作。我在Python中有这个html scrapper,它将在一组特定的<li>之后解析HTML树并提取其text()。问题是其中一些<li>的{​​{1}}内部没有文字。

<i class='ok'></i>

我的xPath选择器目前如下:

<html>
  <body>
    <div>
     <ul>
       <li>Text...</li>
       <li>Other text...</li>
       <li><i class='ok'></i></li>
       <li><i class='ok'></i>Another text...</li>
     </ul>
    </div>
  </body>
</html>

我希望在某些情况下获得类值,但row_value = '(//div[contains(@id,"phone_columns")]' \ '/div/ul[contains(@class,"phone_column_features")]' \ '/li/text() | ' \ '//div[contains(@id,"phone_columns")]' \ '/div/ul[contains(@class,"phone_column_features")]' \ '/li/i/@class)' 中的大多数都会这样做。

当前输出:

text()

期望的输出:

[ "Text...", "Other text...", "ok", "ok", "Another text..." ]

提前致谢, CésarLiedke

1 个答案:

答案 0 :(得分:0)

通常像//li/concat(i/@class, text())这样的XPath应该可以解决问题,但我很确定lxml不支持这种语法。

相反,您可以使用更复杂的代码:

source = lxml.html.fromstring(your_HTML)
li_nodes = source.xpath("//div/ul/li")  # replace this simplified XPath with actual XPath for li nodes

class_values = [i.xpath("./i/@class")[0] if i.xpath("./i/@class") else " " for i in li_nodes]
text_nodes = [i.text_content() if i.text_content() else " " for i in li_nodes]

output = [" ".join(item).strip() for item in zip(class_values, text_nodes)]

print(output)的输出:

['Text...', 'Other text...', 'ok', 'ok Another text...']