如何使用 PowerShell 解析网站的 HTML

tac*_*ght 5 html powershell dom html-parsing

我正在尝试检索有关网站的一些信息,我想查找特定的标签/类,然后返回包含的文本值 (innerHTML)。这是我到目前为止

$request = Invoke-WebRequest -Uri $url -UseBasicParsing
$HTML = New-Object -Com "HTMLFile"
$src = $request.RawContent
$HTML.write($src)


foreach ($obj in $HTML.all) { 
    $obj.getElementsByClassName('some-class-name') 
}
Run Code Online (Sandbox Code Playgroud)

我认为将 HTML 转换为 HTML 对象存在问题,因为当我尝试“选择对象”时看到很多未定义的属性和空的结果。

所以花了两天后,我应该如何用Powershell解析HTML?

因此,由于使用正则表达式解析 HTML 是一个很大的禁忌,否则我该怎么做?似乎没有任何效果。

tac*_*ght 9

由于没有其他人发布答案,我设法使用以下代码获得了一个有效的解决方案:

$request = Invoke-WebRequest -Uri $URL -UseBasicParsing
$HTML = New-Object -Com "HTMLFile"
[string]$htmlBody = $request.Content
$HTML.write([ref]$htmlBody)
$filter = $HTML.getElementsByClassName($htmlClassName)
Run Code Online (Sandbox Code Playgroud)

对于某些 URL,我发现 $filter 变量为空,而其他 URL 则填充了该变量。总而言之,这可能适合您的情况,但似乎 Powershell 并不是进行更复杂解析的方法。

  • 我想指出的是,该解决方案仅适用于 Windows 上部署的 PowerShell。COM 对象通常在 PowerShell v7.xx 中不可用。 (4认同)

小智 5

在 2020 年,使用 PowerShell 5+,您可以这样做:

$searchClass = "banana" <# in this example we parse all elements of class "banana" but you can use any class name you wish #>
$myURI = "url.com" <# replace url.com with any website you want to scrape from #>

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 <# using TLS 1.2 is vitally important #>
$req = Invoke-Webrequest -URI $myURI
$req.ParsedHtml.getElementsByClassName($searchClass) | %{Write-Host $_.innerhtml}

#for extra credit we can parse all the links
$req.ParsedHtml.getElementsByTagName('a') | %{Write-Host $_.href} #outputs all the links

Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,在 2020 年,使用 powershell 7.0.3 时,这不起作用。响应(“$req”)不会有名为 ParsedHtml 的属性。这是 powershell-classic 独有的功能吗? (16认同)
  • @BenR“此参数已被弃用。从 PowerShell 6.0.0 开始,所有 Web 请求仅使用基本解析。包含此参数只是为了向后兼容,任何使用它都不会影响 cmdlet 的操作。” (2认同)

mkl*_*nt0 2

如果可以选择安装第三方模块:

  • PSParseHTML模块包装了HTML Agility Pack [1]和AngleSharp .NET(NuGet 包);您可以使用其中之一进行 HTML 解析;后者需要-Engine AngleSharp选择加入;至于它们各自的DOM(对象模型)

    • 默认情况下使用的 HTML Agility Pack 提供了一个类似于标准NET类型 ( )提供的XML DOM 的对象模型。有关其使用示例,请参阅此答案。System.Xml.XmlDocument[xml]

    • AngleSharp需要选择加入 via -Engine AngleSharp,它是基于官方 W3C 规范构建的,因此提供了可在 Web 浏览器中使用的 HTML DOM。值得注意的是,这意味着它的.QuerySelector()和方法可以与通常的CSS 选择器.QuerySelectorAll()一起使用,如下所示。

  • 使用这个模块的另一个好处是它不仅是跨版本的,而且是跨平台的;也就是说,您可以在Windows PowerShell以及PowerShell (Core) 7+中使用它,并且通过后者也可以在类Unix平台上使用它。


一个基于AngleSharp引擎的独立示例,解析英文维基百科的主页并提取属性值为 的所有HTML元素:classvector-menu-content-list

# Install the PSParseHTML module on demand
If (-not (Get-Module -ErrorAction Ignore -ListAvailable PSParseHTML)) {
  Write-Verbose "Installing PSParseHTML module for the current user..."
  Install-Module -Scope CurrentUser PSParseHTML -ErrorAction Stop
}

# Using the AngleSharp engine, parse the home page of the English Wikipedia
# into an HTML DOM.
$htmlDom = ConvertFrom-Html -Engine AngleSharp -Url https://en.wikipedia.org

# Extract all HTML elements with a 'class' attribute value of 'vector-menu-content-list'
# and output their text content (.TextContent)
$htmlDom.QuerySelectorAll('.vector-menu-content-list').TextContent
Run Code Online (Sandbox Code Playgroud)