使用bash解析HTML页面

问题描述 投票:0回答:3

我有一个Web HTML页面,我试图解析它。

资源 ::

<tr class="active0"><td class=ac><a name="redis/172.29.219.17"></a><a class=lfsb href="#redis/172.29.219.17">172.29.219.17</a></td><td>0</td><td>0</td><td>-</td><td>0</td><td>0</td><td></td><td>0</td><td>0</td><td>-</td><td><u>0<div class=tips><table class=det><tr><th>Cum. sessions:</th><td>0</td></tr><tr><th colspan=3>Avg over last 1024 success. conn.</th></tr><tr><th>- Queue time:</th><td>0</td><td>ms</td></tr><tr><th>- Connect time:</th><td>0</td><td>ms</td></tr><tr><th>- Total time:</th><td>0</td><td>ms</td></tr></table></div></u></td><td>0</td><td>?</td><td>0</td><td>0</td><td></td><td>0</td><td></td><td>0</td><td><u>0<div class=tips>Connection resets during transfers: 0 client, 0 server</div></u></td><td>0</td><td>0</td><td class=ac>17h12m DOWN</td><td class=ac><u> L7TOUT in 1001ms<div class=tips>Layer7 timeout:  at step 6 of tcp-check (expect string &#39;role:master&#39;)</div></u></td><td class=ac>1</td><td class=ac>Y</td><td class=ac>-</td><td><u>1<div class=tips>Failed Health Checks</div></u></td><td>1</td><td>17h12m</td><td class=ac>-</td></tr>
<tr class="backend"><td class=ac><a name="redis/Backend"></a><a class=lfsb href="#redis/Backend">Backend</a></td><td>0</td><td>0</td><td></td><td>1</td><td>24</td><td></td><td>29</td><td>41</td><td>200</td><td><u>5<span class="rls">4</span>033<div class=tips><table class=det><tr><th>Cum. sessions:</th><td>5<span class="rls">4</span>033</td></tr><tr><th>- Queue time:</th><td>0</td><td>ms</td></tr><tr><th>- Connect time:</th><td>0</td><td>ms</td></tr><tr><th>- Total time:</th><td><span class="rls">6</span>094</td><td>ms</td></tr></table></div></u></td><td>5<span class="rls">4</span>033</td><td>1s</td><td><span class="rls">4</span>89<span class="rls">1</span>000</td><td>1<span class="rls">8</span>11<span class="rls">6</span>385<div class=tips>compression: in=0 out=0 bypassed=0 savings=0%</div></td><td>0</td><td>0</td><td></td><td>0</td><td><u>0<div class=tips>Connection resets during transfers: 54004 client, 0 server</div></u></td><td>0</td><td>0</td><td class=ac>17h12m UP</td><td class=ac>&nbsp;</td><td class=ac>1</td><td class=ac>1</td><td class=ac>0</td><td class=ac>&nbsp;</td><td>0</td><td>0s</td><td></td></tr></table><p>

我想要的是::

172.29.219.17 L7TOUT in 1001ms

所以我现在正在尝试的是::

grep redis index.html  | grep 'a name=\"redis\/[0-9]*.*\"' 

提取IP地址。

但正则表达式似乎并没有看到唯一的第一行并返回两行,而IP只在行1中。

我仔细检查使用正则表达式但它似乎没有工作。

有任何想法吗 ?

regex bash awk
3个回答
3
投票

使用xpath中的xmllint表达式及其内置的HTML解析器将产生输出为

ipAddr=$(xmllint --html --xpath "string(//tr[1]/td[1])" html)
172.29.219.17

对于超时值预测,我做了一个手工计算包含该值的td行的数量,结果证明是24

xmllint --html --xpath "string(//tr[1]/td[24]/u[1])" html 

产生一个输出

         L7TOUT in 1001ms
         Layer7 timeout:  at step 6 of tcp-check (expect string 'role:master')

删除空格并仅用Awk提取出所需的部分

xmllint --html --xpath "string(//tr[1]/td[24]/u[1])" html | awk 'NF && /L7TOUT/{gsub(/^[[:space:]]*/,"",$0); print}'
L7TOUT in 1001ms

把变量作为

timeOut=$(xmllint --html --xpath "string(//tr[1]/td[24]/u[1])" html | awk 'NF && /L7TOUT/{gsub(/^[[:space:]]*/,"",$0); print}'

现在,您可以将两个值一起打印为

echo "${ipAddr} ${timeOut}"
172.29.219.17 L7TOUT in 1001ms

版本细节,

xmllint --version
xmllint: using libxml version 20902

你的HTML输入文件</table>中有一个不正确的标签,就在<p>报告为xmllint之前的末尾

htmlfile:147:HTML解析器错误:意外的结束标记:表

在进一步测试之前删除该行。


2
投票

解析复杂的格式,如JSON,XML,HTML,CSS,YAML,...... ETC在bash中非常困难并且可能容易出错。因此我建议使用以下方法之一:

  • PHP
  • 红宝石
  • 蟒蛇
  • GOLANG

因为这些语言是跨平台的,并且具有上述所有格式的解析器。


1
投票

如果要使用正则表达式解析HTML,则必须对HTML格式进行假设。例如。你在这里假设a标签和它的name属性在同一条线上。但是,这也是完美的HTML:

<a
    name="redis/172.29.219.17">
    Some text
</a>

无论如何,让我们唯一的问题是假设a标签在一条线上而name是第一个属性。这就是我能想到的:

  sed 's/\(<a name="redis\)/\n\1/g' index.html | grep '^<a name="redis\/[0-9.]\+"' | sed -e 's/^<a name="redis\///g' -e 's/".*//g'

说明:

  • 第一个sed命令确保所有<a name="redis文本都转到一个单独的行。
  • 然后grep只保留那些以`开头的行
  • 最后一个sed包含两个表达式: 第一个表达式删除了领先的<a name="redis/文本 最后一个表达式删除了关闭"之后的所有内容
© www.soinside.com 2019 - 2024. All rights reserved.