lxml で、あるノードの子孫のノードのみを検索する方法のメモ。
あるノードで node.xpath("//タグ") で検索すると、node が root ノードでなくても
全ノードが検索対象となってしまいます。
子孫のみを検索対象とするには、node.xpath(".//タグ") で検索します。
以下、実行例です。
■id 指定でノードを検索
■//p で検索すると、子孫以外のノードも含まれます
■.//p で検索すると、子孫のノードのみになります
あるノードで node.xpath("//タグ") で検索すると、node が root ノードでなくても
全ノードが検索対象となってしまいます。
子孫のみを検索対象とするには、node.xpath(".//タグ") で検索します。
以下、実行例です。
import sys import lxml.html htmlstr = """ <html> <body> <div id="d1"> <div id="d2-1"> <div id="d3-1"> <p id="p4-1">p4-1 text</p> <p id="p4-2">p4-2 text</p> </div> <div id="d3-2"></div> </div> <div id="d2-2"> <p id="p3-3">p3-3 text</p> <p id="p3-4">p3-4 text</p> </div> </div> </body> </html> """ dom = lxml.html.fromstring(htmlstr)
■id 指定でノードを検索
node = dom.xpath("//div[@id='d3-1']")[0] print(node.tag) print(node.attrib) --> div {'id': 'd3-1'}
■//p で検索すると、子孫以外のノードも含まれます
ps = node.xpath("//p") print(len(ps)) for p in ps: print(p.attrib) --> 4 {'id': 'p4-1'} {'id': 'p4-2'} {'id': 'p3-3'} {'id': 'p3-4'}
■.//p で検索すると、子孫のノードのみになります
ps = node.xpath(".//p") print(len(ps)) for p in ps: print(p.attrib) print(p.text) --> 2 {'id': 'p4-1'} p4-1 text {'id': 'p4-2'} p4-2 text