【问题标题】:How to cut HTML file (drop anything outside two tags)?如何剪切 HTML 文件(删除两个标签之外的任何内容)?
【发布时间】:2018-06-07 13:18:20
【问题描述】:

当这是我的 HTML 示例文档时:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>title</title>
  </head>
  <body>
    <iframe></iframe>
    <div class="text">TEST</div>
    <div id="trend" data-app="openableBox" class="box sub-box">
        <div class="box-header">
            <h1><span>Highlights</span></h1>
        </div>
    </div>
  </body>
</html>

如何提取

<iframe></iframe>
<div class="text">TEST</div>

通过删除所有之前 &lt;iframe&gt; 和之后(开始于)&lt;div id="trend"&gt;?

如果你能帮助我,谢谢。

【问题讨论】:

    标签: html awk sed jq sequential


    【解决方案1】:

    从命令行处理 HTML/XML 数据时 - 应使用适当的 HTML/XML 解析器。
    xmllint 就是其中之一。

    xmllint --html --xpath '//body/*[self::iframe or self::div[@class="text"]]' input.html
    

    输出:

    <iframe></iframe><div class="text">TEST</div>
    

    【讨论】:

    • xmlstarlet 是另一个这样的工具:xmlstarlet sel -t -c '//body/*[self::iframe or self::div[@id="trend"]]' input.html
    • @glennjackman, xmlstarlet 在这种情况下会失败并出现错误:1.html:6.10: Opening and ending tag mismatch: meta line 4 and head &lt;/head&gt; ^ 1.html:16.9: Opening and ending tag mismatch: head line 3 and html &lt;/html&gt; ^ 1.html:17.1: Premature end of data in tag html line 2 。这就是我选择xmllint的原因(因为html输入)
    • 对,需要将meta标签修复为正确的XML。我没有意识到 xmllint 可以处理非 xml html。
    • 当HTML标签分散在多行时它仍然有效吗?
    • @LuisPaganini,在这种方法中,标签占用一行还是多行并不重要
    【解决方案2】:

    这是一个解决一般问题的解决方案,假设一个人想要基于 HTML 的“线性化”选择一系列元素。此方案使用pup 将HTML 转换为JSON,然后使用 执行线性化、选择和转换回HTML。

    program.jq

    这个想法是通过递归地将子级提升到顶层来“线性化”HTML:

    # Emit a stream by hoisting .children recursively.
    # It is assumed that the input is an array, 
    # and that .children is always an array.
    def hoist:
      .[]
      | if type == "object" and has("children")
        then del(.children), (.children | hoist)
        else .
        end;
    
    def indexof(condition):
      label $out
      | foreach .[] as $x (null; .+1;
          if ($x|condition) then .-1, break $out else empty end)
        // null;
    
    # Reconstitute the HTML element
    def toHtml:
      def k: . as $in | (keys_unsorted - ["tag", "text"])
      | reduce .[] as $k (""; . + " \($k)=\"\($in[$k])\"");
      def t: if .text then .text else "" end;
      "<\(.tag)\(k)>\(t)</\(.tag)>"
      ;
    
    # Linearize and then select the desired range of elements
    [hoist]
    | indexof( .tag == "iframe") as $first
    | indexof( .tag == "div" and .id=="trend") as $last
    | .[$first:$last]
    | .[]
    | toHtml
    

    调用:

    pup 'json{}' < input.html | jq -rf program.jq
    

    输出:

    <iframe></iframe>
    <div class="text">TEST</div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 2012-04-10
      相关资源
      最近更新 更多