首页 > 解决方案 > 如何在匹配后提取特定 HTML 标记的内容?

问题描述

我想知道如何在 HTML 中提取超链接的内容,

例如:

<article id="post36">
                <div>
                    <h3><a href="/blog/2019/4-14-canaries-in-the-coal-mine.html">Canaries in the Coal Mine</a></h3>
                    <p class="author">Posted by <a href="/blog/authors/moderator.html" rel="author">Moderator</a></p>
                    <p><time><span>Sunday, April 14th, 2019</span> &mdash; 8:17AM</time></p>
                </div>

其他帖子看起来像这样(没有外部页面):

<article id="post33">
                <div>
                    <h3><a href="#post33">Landlines Win Again</a></h3>
                    <p class="author">Posted by <a href="/blog/authors/moderator.html" rel="author">Moderator</a></p>
                    <p><time><span>Friday, December 21st, 2018</span> &mdash; 7:14AM</time></p>

在外部脚本中,我获得了特定帖子的 ID。在这种情况下,帖子 36 在下面。我有一个页面,其中包含文章标签中的所有帖子元数据,如下所示。

我尝试使用 catting 网页(我有一个本地副本)并将其传送到sed -n 's|[^<]*<article\([^<]*\)</article>[^<]*|\1\n|gp'

那种作品。它只返回所有文章 ID,如下所示:

<article id="post6">
<article id="post5">
<article id="post4">
<article id="post3">
<article id="post2">
<article id="post1">

我的结论是它只适用于当前行。当我尝试实际使用该 ID 时,我什么也没得到:sed -n 's|[^<]*<article id="post36">\([^<]*\)</article>[^<]*|\1\n|gp'

我的问题是如何利用内置的 Unix 工具(sed、grep、awk 等)来提取超链接?在这种情况下,我需要的是/blog/2019/4-14-canaries-in-the-coal-mine.html

是的,我已经查阅了许多 SO 帖子,例如thisthis,其中大多数不鼓励这种事情(我尝试了本机解决方案,但没有一个有效)。两件事情:

  1. HTML 的格式很好。代码中永远不会有任何额外的空格、回车或其他任何内容。块将永远是这样的。这是一个非常具体的应用程序。
  2. 除非在没有某种附加或外部程序的情况下实际上不可能做到这一点,否则我想坚持使用基本的 Unix 工具。

标签: bashhtml-parsing

解决方案


您可以使用sed 地址单出有趣的行。在这种情况下,一个正则表达式模式来匹配<a href

sed -nre '/h3.*href.*(#post[0-9]+|\/blog\/)/ s/.*<a href="([^"]+)".*/\1/p' test.html 
/blog/2019/4-14-canaries-in-the-coal-mine.html
#post33

sed要按文章 ID 匹配,请在命令前面添加此内容

grep -A3 'article id="post36"' test.html | sed -nre '/h3.*href.*(#post[0-9]+|\/blog\/)/ s/.*<a href="([^"]+)".*/\1/p'

推荐阅读