我正在尝试使用PowerShell从网页中提取HTML表格,但是我无法调用表格本身。页面上有两个表,一个用于输入,另一个用于输出,理想情况下我想检查输出表是否包含任何内容(除了指示没有结果的特定字符串),以及是否确实将信息表示为表成文件。
我尝试过使用Invoke-Webrequest
的{{1}}属性,但这些表没有特定的元素名称或ID,也没有“class”或“title”标签来区分二。使用ParsedHtml
属性确实显示了几个COMObject(格式为.IHTMLDocument2_all
),我觉得我需要以某种方式调用以获得我需要的东西,但我无法弄清楚如何这样做。
有没有办法调用那些COMObjects,所以我可以从它们内部提取信息?
以下是我试图从中获取结果的表格的HTML(当没有结果时):
TypeName: System.__ComObject#{3050f539-98b5-11cf-bb82-00aa00bdce0b}
当有结果时,有几个标题用于显示结果,在此代码中:
<Center>
<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=2><TR><TD>
<TABLE CELLSPACING=0 CELLPADDING=2 BORDER=0>
<TR><TD BGCOLOR=3399FF ALIGN=CENTER><NOBR><FONT FACE="Arial" SIZE=+1><B> Search Results </B></FONT></NOBR></TD></TR>
<TR><TD><TABLE WIDTH=100% CELLSPACING=0 CELLPADDING=2 BORDER=0>
<Center>
<table width="100%" cellpadding="5" cellspacing="0">
<tr>
<td>No assets were found for the search</td>
</tr>
</TABLE></TD></TR>
</TABLE></TD></TR>
</TABLE>
</Center>
理想情况下,我想检查资产是否已找到,如果是,请将结果从标题1,2,3,6和7下拉成可用的表单(很可能是表格或.csv文件) )。非常感谢任何帮助。
答案 0 :(得分:1)
好的,所以如果你问周围大多数人会强烈反对使用RegEx解析HTML。他们可能是对的,但我很顽固,觉得RegEx足够灵活,可以处理某些任务,即使在HTML中也是如此。所以我在相关问题中调整了我的答案,以便我认为对你有用。
这依赖于这样一个事实,即包含您要查找的数据的最内层表以行开头:
<table width="100%" cellpadding="5"
...并且没有嵌入其他表格。所以它非常具体,但它适用于您提供的示例。
我在你的例子中创建了一个here-string:
$Sample = @"
<Center>
<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=2><TR><TD>
<TABLE CELLSPACING=0 CELLPADDING=2 BORDER=0>
<TR><TD BGCOLOR=3399FF ALIGN=CENTER><NOBR><FONT FACE="Arial" SIZE=+1><B> Search Results </B></FONT></NOBR></TD></TR>
<TR><TD><TABLE WIDTH=100% CELLSPACING=0 CELLPADDING=2 BORDER=0>
<Center>
<table width="100%" cellpadding="5" cellspacing="0">
<tr bgcolor=A9A9A9>
<th>HEADER1</th>
<th>HEADER2</th>
<th>HEADER3</th>
<th>HEADER4</th>
<th>HEADER5</th>
<th>HEADER6</th>
<th>HEADER7</th>
<th>HEADER8</th>
<th>HEADER9</th>
<th>HEADER10</th>
<th>HEADER11</th>
<th>HEADER12</th>
<th>HEADER13</th>
</tr>
<tr >
<td nowrap><font size= "-1" color=000000>**RESULTSA**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSA**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSA</td>
<td nowrap><font size= "-1" color=000000>**RESULTSA**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSA**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSA**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSA**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSA**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSA**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSA**</td>
<td nowrap><font size= "-1" color=000000> </td>
<td nowrap><font size= "-1" color=000000>**RESULTSA**</td>
<td nowrap><font size= "-1" color=000000> </td>
<tr>
<tr bgcolor=C0C0C0>
<td nowrap><font size= "-1" color=000000>**RESULTSB**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSB**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSB**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSB**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSB**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSB**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSB**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSB**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSB**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSB**</td>
<td nowrap><font size= "-1" color=000000> </td>
<td nowrap><font size= "-1" color=000000>**RESULTSB**</td>
<td nowrap><font size= "-1" color=000000> </td>
<tr>
<tr >
<td nowrap><font size= "-1" color=000000>**RESULTSC**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSC**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSC**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSC**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSC**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSC**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSC**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSC**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSC**</td>
<td nowrap><font size= "-1" color=000000>**RESULTSC**</td>
<td nowrap><font size= "-1" color=000000> </td>
<td nowrap><font size= "-1" color=000000>**RESULTSC**</td>
<td nowrap><font size= "-1" color=000000> </td>
<tr>
</TABLE></TD></TR>
</TABLE></TD></TR>
</TABLE>
</Center>
"@
然后我使用RegEx查找上面提到的特定字符串,并抓取所有内容到下一个</table>
标记。
[regex]$regex = '(?s)<table width="100%" cellpadding="5" .*?</TABLE>'
$tables = $regex.matches($Sample).groups.value
之后,我将其拆分为<tr>
标签以获取单独的行。
ForEach($String in $tables){
$TableRows = $string -split '<tr.*?>'
接下来的三位都是我在变量中捕获的一行。
首先在每一行我查找列或标题,然后我用逗号加入它们。
$CurTable = $TableRows | ForEach-Object{$_ -split "(?s)</T(?:D|H)>.*?<T(?:D|H).*?>" -join ","
然后我替换了剩余的<TD>
,</TD>
,<TH>
和</TH>
标记,以删除任何前导或尾随标记。我还删除了<font>
标签以保持清洁,以及任何换行符,因为任何单个给定行应该只有一行。
-replace "<(/?T(D|H|R|ABLE)|font).*?>" -replace "[\r\n]"
然后从行的开头或结尾修剪任何空格或逗号,并仅输出在其上有文本的行,我们实际上最终得到一个非常标准的CSV。
| ForEach-Object{$_.Trim(' ,')} | ?{![string]::IsNullOrWhiteSpace($_)}
拥有CSV后,您可以轻松地将其转换为对象,只选择所需的属性,然后导出为CSV,或使用Out-GridView
,如果只是Format-Table
,则只需 If($CurTable -is [array]){
$CurTable |ConvertFrom-Csv|Select 'HEADER1','HEADER2','HEADER3','HEADER6','HEADER7' #|Export-Csv "C:\Path\To\Output\Results.csv" -NoTypeInformation
}Else{
$CurTable
}
}
想看文字。或者过滤结果......使用那里的数据非常容易。
现在,有可能没有结果,在这种情况下,你最终得到的只是一个字符串,而不是一个CSV。我所做的是为了检查结果是否是一个数组。如果是数组,则需要使用数据。如果它不是数组,则结果表中没有任何内容,我选择将其输出到屏幕。以下是我处理的方法:
[regex]$regex = '(?s)<table width="100%" cellpadding="5" .*?</TABLE>'
$tables = $regex.matches($Sample).groups.value
ForEach($String in $tables){
$TableRows = $string -split '<tr.*?>'
$CurTable = $tablerows|%{$_ -split "(?s)</T(?:D|H)>.*?<T(?:D|H).*?>" -join "," -replace "<(/?T(D|H|R|ABLE)|font).*?>" -replace "[\r\n]"} | ForEach-Object{$_.Trim(' ,')} | ?{![string]::IsNullOrWhiteSpace($_)}
If($CurTable -is [array]){
$CurTable |ConvertFrom-Csv|Select 'HEADER1','HEADER2','HEADER3','HEADER6','HEADER7' #|Export-Csv "C:\Path\To\Output\Results.csv" -NoTypeInformation
}Else{
$CurTable
}
}
我的回答很长,但实际的功能代码归结为:
HEADER1 : **RESULTSA**
HEADER2 : **RESULTSA**
HEADER3 : **RESULTSA
HEADER6 : **RESULTSA**
HEADER7 : **RESULTSA**
HEADER1 : **RESULTSB**
HEADER2 : **RESULTSB**
HEADER3 : **RESULTSB**
HEADER6 : **RESULTSB**
HEADER7 : **RESULTSB**
HEADER1 : **RESULTSC**
HEADER2 : **RESULTSC**
HEADER3 : **RESULTSC**
HEADER6 : **RESULTSC**
HEADER7 : **RESULTSC**
这将导致:
PagesController
希望这足以让你合作以获得你需要的东西。