在这段 html 代码中:
<div id="ajaxWarningRegion" class="infoFont"></div>
<span id="ajaxStatusRegion"></span>
<form enctype="multipart/form-data" method="post" name="confIPBackupForm" action="/cgi-bin/utilserv/confIPBackup/w_confIPBackup" id="confIPBackupForm" >
<pre>
Creating a new ZIP of IP Phone files from HTTP/PhoneBackup
and HTTPS/PhoneBackup
</pre>
<pre> /tmp/IP_PHONE_BACKUP-2012-Jul-25_15:47:47.zip</pre>
<pre>Reports Success</pre>
<pre></pre>
<a href = /tmp/IP_PHONE_BACKUP-2012-Jul-25_15:47:47.zip>
Download the new ZIP of IP Phone files
</a>
</div>
我想检索文本 IP_PHONE_BACKUP-2012-Jul-25_15:47:47.zip
或只是 IP_PHONE_BACKUP-
和 之间的日期和时间。 zip
我该怎么做?
最佳答案
这个问题之所以如此有趣,是因为 HTML 看起来和闻起来都像 XML,后者由于其良好的行为和有序的结构而更适合编程。在理想世界中,HTML 是 XML 的子集,但现实世界中的 HTML 显然不是 XML。如果您将问题中的示例提供给任何 XML 解析器,它将对各种违规行为犹豫不决。也就是说,使用一行 PowerShell 就可以达到预期的结果。这一个返回 href 的整个文本:
Select-NodeContent $doc.DocumentNode "//a/@href"
这一个提取所需的子字符串:
Select-NodeContent $doc.DocumentNode "//a/@href" "IP_PHONE_BACKUP-(.*)\.zip"
然而,问题在于能够运行那一行代码的开销/设置。你需要:
- 安装 HtmlAgilityPack 使 HTML 解析看起来就像 XML 解析。
- 安装 PowerShell Community Extensions 如果您想解析实时网页。
- 了解 XPath 以便能够构建通向目标节点的可导航路径。
- 了解正则表达式,以便能够从目标节点中提取子字符串。
满足这些要求后,您可以将 HTMLAgilityPath
类型添加到您的环境中并定义 Select-NodeContent
函数,如下所示。代码的最后显示了如何为上述单行代码中使用的 $doc
变量赋值。我将展示如何根据您的需要从文件或 Web 加载 HTML。
Set-StrictMode -Version Latest
$HtmlAgilityPackPath = [System.IO.Path]::Combine((Get-Item $PROFILE).DirectoryName, "bin\HtmlAgilityPack.dll")
Add-Type -Path $HtmlAgilityPackPath
function Select-NodeContent(
[HtmlAgilityPack.HtmlNode]$node,
[string] $xpath,
[string] $regex,
[Object] $default = "")
{
if ($xpath -match "(.*)/@(\w+)$") {
# If standard XPath to retrieve an attribute is given,
# map to supported operations to retrieve the attribute's text.
($xpath, $attribute) = $matches[1], $matches[2]
$resultNode = $node.SelectSingleNode($xpath)
$text = ?: { $resultNode } { $resultNode.Attributes[$attribute].Value } { $default }
}
else { # retrieve an element's text
$resultNode = $node.SelectSingleNode($xpath)
$text = ?: { $resultNode } { $resultNode.InnerText } { $default }
}
# If a regex is given, use it to extract a substring from the text
if ($regex) {
if ($text -match $regex) { $text = $matches[1] }
else { $text = $default }
}
return $text
}
$doc = New-Object HtmlAgilityPack.HtmlDocument
$result = $doc.Load("tmp\temp.html") # Use this to load a file
#$result = $doc.LoadHtml((Get-HttpResource $url)) # Use this PSCX cmdlet to load a live web page
关于html - 使用 powershell 检索 HTML 中的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11651431/