使用 xmllint 解析 html

Parse html with xmllint

我有一个 HTML 这样的代码

<dl>
 <dt><a href="element1" id="element1">element1</a> Version 1 </dt>
 <dd>Description 1</dd>
 <dt><a href="element2" id="element2">element2</a> Version 2 </dt>
 <dd>Description 2</dd>
...
</dl>

我想打印一个像

这样的输出
Item: element1, Version: Version1, Description: Description 1
Item: element2, Version: Version2, Description: Description 2
...

我尝试了几种方法,但我最好的方法是:

xmllint --xpath "concat('Item: ', //dl/dt/a/text(),', Version: ',', Description: ',//dl/dd/text())" file

#output
Item: element1, Version: , Description: Description 1

问题:

如果您不必坚持使用 xmllint,这里是完成工作的纯粹 bash 方法:

cat file | tr '>' '\n' | grep '.\+</' | cut -d '<' -f 1 | awk '{ if (NR%3==1) print "Item: "[=10=]","; if (NR%3==2) print "Version: "[=10=]","; if (NR%3==0) print "Description: "[=10=];}' | paste -sd '  \n' -

解释:

管道的第一部分:提取感兴趣的数据

cat file | tr '>' '\n' | grep '.\+</' | cut -d '<' -f 1

这输出:

element1
Version 1
Description 1
element2
Version 2
Description 2

管道的第二部分:基于行号的前缀名称

awk '{ if (NR%3==1) print "Item: "[=13=]","; if (NR%3==2) print "Version: "[=13=]","; if (NR%3==0) print "Description: "[=13=];}'

这输出:

Item: element1,
Version:  Version 1 ,
Description: Description 1
Item: element2,
Version:  Version 2 ,
Description: Description 2

管道的最后部分:每 3 行缝合一次

paste -sd '  \n' -

这样就输出了你想要的最终结果。

你可以使用htql。例如:

text="""<dl>
 <dt><a href="element1" id="element1">element1</a> Version 1 </dt>
 <dd>Description 1</dd>
 <dt><a href="element2" id="element2">element2</a> Version 2 </dt>
 <dd>Description 2</dd>
...
</dl>"""

import htql
results = htql.query(text, "<dl>.<dt sep>2-0 {Item=<a>:tx; Version=<a>:xx; Description=<dd>:tx }")

然后显示结果:

>>> results
[('element1', ' Version 1 ', 'Description 1'), ('element2', ' Version 2 ', 'Description 2')]

根据@seagulf 的建议,使用 python、

更容易
results = htql.query(mystr, "<dl>.<dt sep>2-0 {Item=<a>:tx; Version=<a>:xx; Description=<dd>:tx } \n")
for x in results:
    f.write ('{"item": "'+ x[0] + '", "version" : "' + x[1] + '", "description" : "' + x[2] + '"},\n')

#output
{"item": "element 1", "version" : "version 1", "description" : "description 1"},
{"item": "element 2", "version" : "version 2", "description" : "description 2"},
...

非常感谢!