如何用PowerShell提取嵌套DOM元素中的指定内容?
PowerShell链式调用DOM方法失效的原因及解决
问题场景
需要提取网页中class为school的div下,class为count的span中的数值(示例中的52)。网页DOM结构如下:
[...] <div class="school"> <span class="count">52</span> <span class="text">Some text</span> </div> <div class="home"> <span class="count">33</span> <span class="text">Some text</span> </div> [...]
已通过分步代码实现需求:
$url = 'https://url.com/something' $html = Invoke-WebRequest $url $school = $html.ParsedHtml.body.getElementsByTagName('div') | Where {$_.getAttributeNode('class').Value -eq 'school'} $count = $school.getElementsByTagName('span') | Where {$_.getAttributeNode('class').Value -eq 'count'}
但尝试链式调用时无法生效:
$school = $html.ParsedHtml.body.getElementsByTagName('div') | Where {$_.getAttributeNode('class').Value -eq 'school'} | getElementsByTagName('span') | Where {$_.getAttributeNode('class').Value -eq 'count'}
失效原因
核心问题在于PowerShell管道的处理逻辑:
Where-Object(简写Where)输出的是DOM元素对象(这里是单个div.school元素)getElementsByTagName是DOM元素的实例方法,而非PowerShell内置的cmdlet或函数- 直接在管道中写
getElementsByTagName('span')时,PowerShell会尝试寻找同名的管道命令,而非调用前一个对象的实例方法,因此链式调用无法正确执行
修复后的链式调用写法
要在管道中调用对象的实例方法,需要借助ForEach-Object(简写%)来执行:
$count = $html.ParsedHtml.body.getElementsByTagName('div') | Where {$_.getAttributeNode('class').Value -eq 'school'} | ForEach-Object { $_.getElementsByTagName('span') } | Where {$_.getAttributeNode('class').Value -eq 'count'}
这样就能通过链式调用正确筛选出目标元素。
内容的提问来源于stack exchange,提问作者Fridleif
相关产品推荐
相关产品推荐

