2014-09-19 118 views
4

我利用PAL工具(https://pal.codeplex.com/)從Windows中的perfmon日誌生成HTML報告。在PAL處理來自perfmon的.blg文件後,它將信息轉儲到一個HTML文檔中,該文檔包含具有關於系統如何執行的各種數據點的表格。我目前正在編寫一個腳本,查看所有HTML文件的目錄內容,並在所有HTML文件上執行get-content。如何使用native powershell命令從html文件中提取特定表格?

我想要做的是爲具有不同數量的行的特定表格刮取此獲取內容Blob的轉儲。是否有可能使用本地PowerShell cmdlet來查找特定的表,計算每個表中有多少行,並轉儲只需所需的表和錶行?

下面是表格式,我想刮的例子:

<H3>Overall Counter Instance Statistics</H3> 
<TABLE ID="table6" BORDER=1 CELLPADDING=2> 
<TR><TH><B>Condition</B></TH><TH><B>\LogicalDisk(*)\Disk Transfers/sec</B></TH><TH><B>Min</B></TH><TH><B>Avg</B></TH><TH><B>Max</B></TH><TH><B>Hourly Trend</B></TH><TH><B>Std Deviation</B></TH><TH><B>10% of Outliers Removed</B></TH><TH><B>20% of Outliers Removed</B></TH><TH><B>30% of Outliers Removed</B></TH></TR> 
<TR><TD>No Thresholds</TD><TD>MACHINENAME/C:</TD><TD>1</TD><TD>7</TD><TD>310</TD><TD>0</TD><TD>11</TD><TD>5</TD><TD>5</TD><TD>5</TD></TR> 
<TR><TD>No Thresholds</TD><TD>MACHINENAME/D:</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD></TR> 
<TR><TD>No Thresholds</TD><TD>MACHINENAME/E:</TD><TD>0</TD><TD>24</TD><TD>164</TD><TD>-1</TD><TD>11</TD><TD>22</TD><TD>21</TD><TD>20</TD></TR> 
<TR><TD>No Thresholds</TD><TD>MACHINENAME/HarddiskVolume5</TD><TD>0</TD><TD>0</TD><TD>2</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD></TR> 
<TR><TD>No Thresholds</TD><TD>MACHINENAME/L:</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD></TR> 
<TR><TD>No Thresholds</TD><TD>MACHINENAME/T:</TD><TD>0</TD><TD>7</TD><TD>430</TD><TD>0</TD><TD>21</TD><TD>3</TD><TD>2</TD><TD>2</TD></TR> 
</TABLE> 

表ID是所有輸出文件中不變的,但表中的行量不大。任何幫助表示讚賞!

+0

你需要表中的特定行還是整個表? – Grice 2014-09-19 18:52:28

+0

我需要整個表格。我不只是需要一張桌子;我將抓取多個表格並將信息彙總到一個CSV文件中,以便輕鬆導入excel。 – 2014-09-19 18:54:06

+0

你認爲「本地命令」是什麼? PS沒有解析HTML _files_的任何庫存cmdlet,但是如果您安裝了IE,則可以通過「New-Object -ComObject InternetExplorer.Application」執行IE自動化。然後,您可以使用[GetElementById .NET方法](http://msdn.microsoft.com/zh-cn/library/system.windows.forms.htmldocument.getelementbyid%28v=vs.110%29.aspx) 。 – 2014-09-19 18:57:25

回答

6

OK,這是不全面的測試,但您的示例表工作在PS 2.0 IE11:

# Parsing HTML with IE. 
$oIE = New-Object -ComObject InternetExplorer.Application 
$oIE.Navigate("file.html") 
$oHtmlDoc = $oIE.Document 

# Getting table by ID. 
$oTable = $oHtmlDoc.getElementByID("table6") 

# Extracting table rows as a collection. 
$oTbody = $oTable.childNodes | Where-Object { $_.tagName -eq "tbody" } 
$cTrs = $oTbody.childNodes | Where-Object { $_.tagName -eq "tr" } 

# Creating a collection of table headers. 
$cThs = $cTrs[0].childNodes | Where-Object { $_.tagName -eq "th" } 
$cHeaders = @() 
foreach ($oTh in $cThs) { 
    $cHeaders += ` 
     ($oTh.childNodes | Where-Object { $_.tagName -eq "b" }).innerHTML 
} 

# Converting rows to a collection of PS objects exportable to CSV. 
$cCsv = @() 
foreach ($oTr in $cTrs) { 
    $cTds = $oTr.childNodes | Where-Object { $_.tagName -eq "td" } 
    # Skipping the first row (headers). 
    if ([String]::IsNullOrEmpty($cTds)) { continue } 
    $oRow = New-Object PSObject 
    for ($i = 0; $i -lt $cHeaders.Count; $i++) { 
     $oRow | Add-Member -MemberType NoteProperty -Name $cHeaders[$i] ` 
      -Value $cTds[$i].innerHTML 
    } 
    $cCsv += $oRow 
} 

# Closing IE. 
$oIE.Quit() 

# Exporting CSV. 
$cCsv | Export-Csv -Path "file.csv" -NoTypeInformation 

老實說,我沒有瞄準最佳代碼。這只是您如何使用PS中的DOM對象並將其轉換爲PS對象的一個​​示例。

+0

謝謝!你一直是一個巨大的幫助!我只是使用我的一個本地HTML文件對其進行了測試,並解析了表6中的信息。我將破解你的腳本,看看能否輸出其他表的內容。 – 2014-09-19 20:47:11

5

我看到你接受了一個答案,但我想我也會在這裏添加RegEx解決方案。沒有COM對象需要這個,並且應該是PSv2友好的,我很確定。

$Path = 'C:\Path\To\File.html' 
[regex]$regex = "(?s)<TABLE ID=.*?</TABLE>" 
$tables = $regex.matches((GC C:\Temp\test.txt -raw)).groups.value 
ForEach($String in $tables){ 
    $table = $string.split("`n") 
    $CurTable = @() 
    $CurTableName = ([regex]'TABLE ID="([^"]*)"').matches($table[0]).groups[1].value 
    $CurTable += ($table[1] -replace "</B></TH><TH><B>",",") -replace "</?(TR|TH|B)>" 
    $CurTable += $table[2..($table.count-2)]|ForEach{$_ -replace "</TD><TD>","," -replace "</?T(D|R)>"} 
    $CurTable | convertfrom-csv | export-csv "C:\Path\To\Output\$CurTableName.csv" -notype 
} 

這應該爲找到的每個表格輸出一個CSV文件。如table6.csv,table9.csv等,如果你想每個HTML文件輸出CSV格式,你可以包住整個事情在foreach循環,如:

ForEach($File in (Get-ChildItem "$Path\*.html")){ 
    Insert above code here 
} 

你會需要修改$tables =線,使其是GC $file.fullname,它會載入每個文件,因爲它迭代。

然後,只需修改出口-CSV喜歡的東西:

$CurTable | convertfrom-csv | export-csv "C:\Path\To\Output\$($File.BaseName)\$CurTableName.csv" -notype 

所以,如果你有Server01.html在這3個表,你會得到一個名爲Server01的文件夾,在它3 CSV文件,一個文件每張桌子。

相關問題