我试图通过PowerShell进行一些网页抓取,因为我最近发现可以在没有太多麻烦的情况下这样做。在PowerShell的mshtml.HTMLDocumentClass对象上使用querySelectorAll会导致崩溃
一个很好的出发点是只取HTML,使用Get-Member,看看我能做些什么从那里,就像这样:
$html = Invoke-WebRequest "https://www.google.com"
$html.ParsedHtml | Get-Member
的方法提供给我用于获取特定元素出现如下所示:
getElementById()
getElementsByName()
getElementsByTagName()
例如,我可以拿到第一IMG标签的文档中,像这样:
$html.ParsedHtml.getElementsByTagName("img")[0]
但是到我是否可以使用CSS选择器或XPath做一些更多的研究后,我发现有未上市可用的方法,因为我们只是使用了HTML文档对象documented here:
querySelector()
querySelectorAll()
所以不是这样做的:
$html.ParsedHtml.getElementsByTagName("img")[0]
我可以这样做:
$html.ParsedHtml.querySelector("img")
所以我期待能够做到:
$html.ParsedHtml.querySelectorAll("img")
...为了获得所有的IMG元素。我发现的所有文档和我已经完成的搜索结果都支持这一点。然而,在我所有的测试中,这个函数崩溃了调用进程,并在事件日志(0xc0000374)中报告堆损坏异常代码。
我在Windows 10 x64上使用PowerShell 5。我已经在Win10 x64虚拟机中试过了,它是一个干净的版本,只是补丁。我也在Win7 x64升级到PowerShell 5的时候尝试了它。在PowerShell 5之前,我还没有尝试过它,因为我们所有的系统都升级了,但是我可能会有一次有时间为一个新的vanilla虚拟机进行测试。
有没有人跑过这个问题呢?到目前为止,我所有的研究都是死路一条。是否有替代querySelectorAll?我需要在不可预知的布局内部放置可预测的标签集,并且可能没有分配给标签的ID或类,因此我希望能够使用允许结构/嵌套/通配符的选择器。
P.S.我也尝试在PowerShell中使用InternetExplorer.Application COM对象,结果是一样的,除了PowerShell崩溃Internet Explorer崩溃之外。其实,这是我原来的做法,下面的代码:
# create browser object
$ie = New-Object -ComObject InternetExplorer.Application
# make browser visible for debugging, otherwise this isn't necessary for function
$ie.Visible = $true
# browse to page
$ie.Navigate("https://www.google.com")
# wait till browser is not busy
Do { Start-Sleep -m 100 } Until (!$ie.Busy)
# this works
$ie.document.getElementsByTagName("img")[0]
# this works as well
$ie.document.querySelector("img")
# blow it up
$ie.document.querySelectorAll("img")
# we wanna quit the process, but since we blew it up we don't really make it here
$ie.Quit()
希望我没有违反任何规则和这个职位是有道理的,是相关的,谢谢。
UPDATE
我测试了早期版本的PowerShell。 v2-v4使用InternetExplorer.Application COM方法崩溃。 v3-4使用Invoke-WebRequest方法崩溃,v2不支持它。
感谢您的回应,这肯定是有见地的。我可以按照你的建议进行操作,我可以在'$ PsNodeList'数组中填入'$ NodeList'元素。但是,我注意到这只有在使用'Invoke-WebRequest'时才有效。如果使用'New-Object -ComObject InternetExplorer.Application',它会抛出'异常来自HRESULT:0x80020101' :( 我试图做一个交互式刮板,所以如果可能的话,我宁愿使用IE ComObject。我会继续研究,现在,至少很高兴知道有''Invoke-WebRequest'的结果有一个解决方法 – TheKojukinator
嗯,我无法得到OP IE“工作”代码,直到我使用32位Powershell但是我的最大努力无法让它返回'.item()'的结果。 哎呦命中输入...仍然编辑 我确实得到了真正的聪明人的攻击,做了一些很酷的事情,但没有回到Powershell到目前为止 我说:“拧它,我们有DOM,让我们插入一些JavaScript。”所以这个Powershell代码注入'
@ midnightfreddie的解决方案对我来说工作得很好,但现在调用时抛出
Exception from HRESULT: 0x80020101
。我发现了以下解决方法:为
New-Object -ComObject InternetExplorer.Application
这一个工程,以及。
来源
2016-12-06 18:30:58