PowerShell 小技 - 下載並解析 HTML DOM
0 |
遇到用 PowerShell 爬網頁並簡單解析 HTML 取資料的需求,為此研究了做法,筆記備忘。
如果是 PowerShell 5.1,Invoke-WebRequest 背後是用 WebClient,傳回 Response 物件有個 ParsedHtml 屬性 背後是超古老的 IHTMLDocument2,基本上可以想成是 IE,所以使用上會有不少限制。像是網頁若與 IE 不相容時會壞掉,原本想跑 querySelectorAll() 快速找到目標元素卻到 PowerShell 整個崩潰終止... 等,逼得我只能自己套 Where / Select 實作選取邏輯:
$resp = Invoke-WebRequest -Uri https://blog.darkthread.net
$doc = $resp.ParsedHtml.documentElement.ownerDocument
$doc.title
# 用 $doc.all | Where 實現 querySelectorAll 效果
$doc.all | Where-Object { $_.tagName -eq 'H1' -and $_.getAttribute('itemprop') -match 'headline' } |
Select-Object -First 3 | ForEach-Object {
$link = $_.getElementsByTagName('a')[0]
"[{0}]({1})" -f $link.innerText, $link.href
}
# 以下會造成 PowerShell 崩潰結束
$doc.querySelectorAll('h1[itemprop=headline] a') | ForEach-Object {
$_.outerHTML
"[{0}]({1})" -f $_.innerText, $_.href
}
測試抓取前三篇文章標題及連結 OK,querySelectorAll() 則會害 PowerShell 整個當掉。
因為以上問題,加上 IHTMLDocument2 / IE 己退役且是 Windows 獨有,無法跨平台,PowerShell 6+ 起也不再支援,必須另謀他法。
查到有個 PSParseHTML Module 封裝了 .NET 有名的 HTML 處理程式庫 AngleSharp(支援 QuerySelectorAll()) 及 Html Agility Pack(只能用 XPATH 查,較不好用),Stackoverflow 上有網友寫好的自動下載安裝腳本。
小試了一下改用 PSParseHTML 並移師 Linux 執行,成功!
# 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
}
$htmlDom = ConvertFrom-Html -Engine AngleSharp -Url https://blog.darkthread.net
$htmlDom.QuerySelector('title').TextContent
$htmlDom.QuerySelectorAll('h1[itemprop*=headline] a') |
Select-Object -First 3 | ForEach-Object {
"[{0}]({1})" -f $_.TextContent, $_.Href
}
發現沒裝過 PSParseHTML 模組時會自動下載安裝,接著順利執行 .QuerySelectorAll('h1[itemprop*=headline] a')
得到結果。
Exploring how to scrape and parse HTML using PowerShell, I found that while Invoke-WebRequest in PowerShell 5.1 has limitations, the PSParseHTML module, which uses AngleSharp and Html Agility Pack, offers a more reliable and cross-platform solution. This post details the setup and usage of PSParseHTML for web scraping tasks.
Comments
Be the first to post a comment