问题
什么工具(最好用于 Linux)可以根据 CSS 路径选择 HTML 元素的内容?
例子
例如,考虑以下 HTML 文档:
<html>
<body>
<div class="header">
<h1>Header</h1>
</div>
<div class="content">
<table>
<tbody>
<tr><td class="data">Tabular Content 1</td></tr>
<tr><td class="data">Tabular Content 2</td></tr>
</tbody>
</table>
</div>
<div class="footer">
<p>Footer</p>
</div>
</body>
</html>
哪个命令行程序(例如,一种“cssgrep”)可以使用 CSS 选择器提取值?即:
cssgrep page.html "body > div.content > table > tbody > tr > td.data"
该程序会将以下内容写入标准输出:
Tabular Content 1
Tabular Content 2
相关链接
- https://getfirebug.com/wiki/index.php/Command_Line_API#.24.24.28selector.29
- https://stackoverflow.com/questions/7334942/is-there-something-like-a-css-selector-or-xpath-grep
- https://github.com/keeganstreet/element-finder
- http://www.w3.org/Tools/HTML-XML-utils/
谢谢你!
答案1
使用W3C 工具使用 CSS 选择器解析 HTML/XML 并提取内容。例如:
hxnormalize -l 240 -x filename.html | hxselect -s '\n' -c "td.data"
将产生所需的输出:
Tabular Content 1
Tabular Content 2
使用 240 个字符的行长可确保内容较长的元素不会拆分到多行中。该hxnormalize -x
命令会创建一个格式良好的 XML 文档,可供使用hxselect
。
答案2
CSS 解决方案
Element Finder 命令将部分完成此任务:
- https://github.com/keeganstreet/element-finder
- http://keegan.st/2012/06/03/find-in-files-with-css-selectors/
例如:
elfinder -j -s td.data -x "html"
这将以 JSON 格式呈现结果,可供提取。
XML 解决方案
这XML::Twig模块(“ sudo apt-get install xml-twig-tools
”)附带了一个名为的工具xml_grep
,它可以做到这一点,当然前提是您的 HTML 格式正确。
抱歉,我目前无法测试这一点,但这样的方法应该可行:
xml_grep -t '*/div[@class="content"]/table/tbody/tr/td[@class="data"]' file.html
答案3
https://github.com/ericchiang/pup(https://github.com/htmlparser/htmlparser) 具有基于 CSS 的查询语言,与您的示例非常吻合。事实上,使用您的输入,以下命令:
pup "body > div.content > table > tbody > tr > td.data text{}"
生成:
Tabular Content 1
Tabular Content 2
尾随text{}
删除 HTML 标签。
一个很好的特性是不需要给出完整的路径,因此再次使用你的例子:
$ pup 'td.data text{}' < input.html
Tabular Content 1
Tabular Content 2
它的一个优点pup
是它使用 golang.org/x/net/html 包来解析 HTML5。
答案4
Node 可以使用 JQuery 和伪 DOM 来实现这一点。
我为此制作了一个 Docker 镜像(https://hub.docker.com/r/phil294/jquery-jsdom/):
docker run --rm -i phil294/jquery-jsdom '$("body > div.content > table > tbody > tr > td.data").text()' < page.html
第二个参数是 JavaScript 代码,因此您实际上可以做任何您想做的事情。