使用 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"},
...
非常感谢!
我有一个 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"},
...
非常感谢!