Windows PowerShell 解析本地 HTML 文件。

3
我希望使用PowerShell从HTML文件中构建数组。
我正在使用一个脚本从Mozilla Firefox Developer Edition(下载index文件)下载HTML文件,并希望解析它以获取具有id_country设置的select元素内options元素的值。
我已经被建议使用XPath,但我无法弄清楚如何解析文件并从结果构建数组。也许使用正则表达式可以解决问题。
HTML文件在这里:

http://pastebin.com/b8cShFLA

我希望在这里列出所有选项元素的值:

<select aria-required="true" id="id_country" name="country" required="required">
   <option value="af">Afghanistan</option>
   <option value="al">Albania</option>
   <option value="dz">Algeria</option>
   <option value="as">American Samoa</option>
   <option value="ad">Andorra</option>

...

我对PowerShell还比较陌生,不太清楚可能能用到的不同解决方案。由于这是包安装程序的一部分,所以我需要一个相当快的东西。
基本上,脚本将尝试查看是否有与用户计算机区域设置匹配的安装程序,如果没有,则默认为英语,因此我需要从该列表中获取值以检查Firefox Dev可用的语言环境。
问候, O
3个回答

5
如果您正在运行PS 3.0或更高版本,则可以利用Invoke-WebRequest访问网络上存在的页面。如果您操作的是本地文件,则会有一些问题it can be a bit finicky
Invoke-WebRequest返回一个HtmlWebResponseObject,其中包含一个名为ParsedHtml的属性。由于我们知道在您的选择标记上有id“id_country”,因此我们可以使用该对象的getElementById方法。从那里开始,只需要迭代选项标记并过滤以返回我们想要的属性...“文本”和“值”。
下面的示例输出一个包含国家名称和国家代码的自定义对象:
代码:
# I'm using your raw pastebin endpoint for this example
$result = Invoke-WebRequest "http://pastebin.com/raw.php?i=b8cShFLA"

# Only return specific properties from the elements you're looking for
$countries = $result.ParsedHtml.getElementById("id_country") | 
    Where tagName -eq "option" | 
    Select -Property Text, Value

# Country name and code are stored to this variable
$countries

输出:

text                                                        value
----                                                        -----
Afghanistan                                                 af
Albania                                                     al
Algeria                                                     dz
American Samoa                                              as
Andorra                                                     ad
...                                                         ...

您可以像使用其他powershell对象的属性一样使用国家名称和代码。关于Web端点,听起来您可以修改此脚本以指向提取此HTML的原始Mozilla页面?

似乎没有广泛记录的是从PowerShell 5.1到PowerShell 7.x的这种变化:不再支持file://和ftp:// URI方案。https://learn.microsoft.com/en-us/powershell/scripting/whats-new/differences-from-windows-powershell?view=powershell-7.3碰巧,我正在运行PowerShell 5.1,所以我仍然不明白为什么我无法解析本地文件URI而成功解析托管URI。只是分享信息。文档和示例的匮乏可能会让我回到Python来完成这个任务。只是为未来的挣扎者分享信息。 - 504more
对于PowerShell 5.1用户,此处提供的$localUri字符串可在浏览器中使用,并使用GetType()返回一个WebResponseObject: $localUri = "file:///C:/Folder/File.hml" - 504more

5

我没有看到需要修复的代码示例,所以我会自己写一个。

如果它是一个远程HTML文件,我会使用Invoke-WebRequest,但这对于本地文件并不起作用。

对于解析本地文件,我建议使用HTML Agility Pack来解析HTML文件,然后使用xPath获取您要查找的选项。例如:

Add-Type -Path .\HTMLAgilityPack\HtmlAgilityPack.dll
$url = (get-item .\b8cShFLA.html).FullName

$doc = New-Object HtmlAgilityPack.HtmlDocument
$doc.LoadHtml((get-content $url))

#Create hashtable to store data in
$langs = @{}

$doc.DocumentNode.SelectSingleNode("//select[@name='country']").SelectNodes("option") | ForEach-Object {
    $short = $_.Attributes[0].Value
    $long = $_.NextSibling.InnerText

    #Store data in hashtable
    $langs[$short] = $long
}

$langs

输出:

Name                           Value
----                           -----
rw                             Rwanda
tv                             Tuvalu
to                             Tonga
pn                             Pitcairn
bh                             Bahrain
lc                             Saint Lucia   

0

1
这假设内容是格式良好的,而HTML通常不是。 - Robert Mooney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接