如何通过 ID 提取 HTML 标签?
How to extract an HTML tag by ID?
如何通过 ID 提取页面上的 HTML 内容?
我尝试探索 sed/grep 一个小时的解决方案。 None 成功了。
然后我放弃并探索了 HTML/XML 解析器。 html-xml-utils只能通过class获取元素,不能通过ID获取元素,完全没用。查了手册,好像没办法通过id获取。
xmlstarlet 似乎更有前途,但当我尝试将 HTML 文件而不是 XML 文件传递给它时,它发出抱怨。以下吐出至少 100 个错误:
cat /home/com/interlinked/blog.html | tail -n +2 | xmlstarlet sel -T -t -m '/div/article[@id="post33"]' -v '.' -n
我在这里使用了cat,因为我不想修改实际的文件。我使用 tail 删除了之前似乎引起问题的 DOCTYPE 声明:Extra content at the end of the document
页面上的内容格式正确且内容完整。内容如下所示:
<article id="post44">
... more HTML tags and content here...
</article>
我希望能够通过 ID 提取特定文章标签之间的所有内容(例如,如果我传递“44”,它将 return post44 的内容,如果我传给它 34,它会 return post34).
的内容
这个问题与其他问题的不同之处在于我 不 只想要内容,我想要文章标签之间的实际 HTML。我不需要文章标签本身,尽管删除它们可能是微不足道的。
有没有办法使用内置的 Unix 工具或 xmlstarlet 或 html-xml-utils 来做到这一点?我还尝试了以下 sed,但也无法正常工作:
article=`patt=$(printf 'article id="post%d"' ); sed -n '/<$patt>/,/<\/article>/{ /article>/d; p }' $file`
这里我将文件路径作为 $file 传递,$1 是博客 post ID(44 或 34 或其他)。两个语句合二为一的原因是 $1 不会在 sed 语句中被评估,否则因为单引号。这有助于在相关的 grep 命令中解析变量,但不会在此 sed 命令中解析。
完整的HTML结构:
<!doctype html>
<html lang="en">
<head>
<title>Page</title>
</head>
<body>
<header>
<nav>
<div id="sitelogo">
<a href="/"><img src="/img/logo/logo.png" alt="InterLinked"></img></a>
</div>
<ul>
<p>Menu</p>
</ul>
</nav>
<hr>
</header>
<div id="main">
<h1>Blog</h1>
<div id="bloglisting">
<article id="post44">
<p>Content</p>
</article>
<article id="post43">
</p>Content</p>
</article>
</div>
</div>
</body>
</html>
另外,澄清一下,我需要它在 2 个不同的页面上工作。一些 posts 在这个主页上是内联的,但更长的有自己的页面。结构相似,但不完全相同。如果可能的话,我想要一个只找到 ID 并且不需要担心父标签的解决方案。文章标签本身在两种页面上的格式相同。例如,在一个较长的博客 post 上有自己的页面,不同之处在于:
<div id="main">
<h1>Why Ridesharing Is Evil</h1>
<div id="blogpost">
<article id="post43">
<div>
在这种情况下,div 博客列表变为博客post。这真的是唯一的大区别。
您可以使用 libxml2
工具以正确的语法意识正确解析 HTML/XML。对于您的情况,您可以使用 xmllint
并要求它解析带有标志 --html
的 HTML 文件,并提供来自 top-level 的 xpath
查询以获取节点任您选择。
例如要获取 post id post43
的内容,请使用类似
的过滤器
xmllint --html --xpath \
"//html/body/div[@id='main']/div[@id='bloglisting']/article[@id='post43']" html
如果在您的机器上编译的 xmllint
不理解一些最近的 (HTML5) 标签,如 <article>
或 <nav>
,通过添加 2>/dev/null
在命令的末尾。
如果您只想获取 <article>
中的内容而没有标签本身,请通过管道将结果传递给 sed
来删除第一行和最后一行,如下所示。
xmllint --html --xpath \
"//html/body/div[@id='main']/div[@id='bloglisting']/article[@id='post43']" html 2>/dev/null |
sed '1d; $d'
要为 post-id 使用变量,请定义一个 shell 变量并在 xpath
查询
中使用它
postID="post43"
xmllint --html --xpath \
"//html/body/div[@id='main']/div[@id='bloglisting']/article[@id='"$postID"']" html 2>/dev/null |
sed '1d; $d'
如何通过 ID 提取页面上的 HTML 内容?
我尝试探索 sed/grep 一个小时的解决方案。 None 成功了。 然后我放弃并探索了 HTML/XML 解析器。 html-xml-utils只能通过class获取元素,不能通过ID获取元素,完全没用。查了手册,好像没办法通过id获取。
xmlstarlet 似乎更有前途,但当我尝试将 HTML 文件而不是 XML 文件传递给它时,它发出抱怨。以下吐出至少 100 个错误:
cat /home/com/interlinked/blog.html | tail -n +2 | xmlstarlet sel -T -t -m '/div/article[@id="post33"]' -v '.' -n
我在这里使用了cat,因为我不想修改实际的文件。我使用 tail 删除了之前似乎引起问题的 DOCTYPE 声明:Extra content at the end of the document
页面上的内容格式正确且内容完整。内容如下所示:
<article id="post44">
... more HTML tags and content here...
</article>
我希望能够通过 ID 提取特定文章标签之间的所有内容(例如,如果我传递“44”,它将 return post44 的内容,如果我传给它 34,它会 return post34).
的内容这个问题与其他问题的不同之处在于我 不 只想要内容,我想要文章标签之间的实际 HTML。我不需要文章标签本身,尽管删除它们可能是微不足道的。
有没有办法使用内置的 Unix 工具或 xmlstarlet 或 html-xml-utils 来做到这一点?我还尝试了以下 sed,但也无法正常工作:
article=`patt=$(printf 'article id="post%d"' ); sed -n '/<$patt>/,/<\/article>/{ /article>/d; p }' $file`
这里我将文件路径作为 $file 传递,$1 是博客 post ID(44 或 34 或其他)。两个语句合二为一的原因是 $1 不会在 sed 语句中被评估,否则因为单引号。这有助于在相关的 grep 命令中解析变量,但不会在此 sed 命令中解析。
完整的HTML结构:
<!doctype html>
<html lang="en">
<head>
<title>Page</title>
</head>
<body>
<header>
<nav>
<div id="sitelogo">
<a href="/"><img src="/img/logo/logo.png" alt="InterLinked"></img></a>
</div>
<ul>
<p>Menu</p>
</ul>
</nav>
<hr>
</header>
<div id="main">
<h1>Blog</h1>
<div id="bloglisting">
<article id="post44">
<p>Content</p>
</article>
<article id="post43">
</p>Content</p>
</article>
</div>
</div>
</body>
</html>
另外,澄清一下,我需要它在 2 个不同的页面上工作。一些 posts 在这个主页上是内联的,但更长的有自己的页面。结构相似,但不完全相同。如果可能的话,我想要一个只找到 ID 并且不需要担心父标签的解决方案。文章标签本身在两种页面上的格式相同。例如,在一个较长的博客 post 上有自己的页面,不同之处在于:
<div id="main">
<h1>Why Ridesharing Is Evil</h1>
<div id="blogpost">
<article id="post43">
<div>
在这种情况下,div 博客列表变为博客post。这真的是唯一的大区别。
您可以使用 libxml2
工具以正确的语法意识正确解析 HTML/XML。对于您的情况,您可以使用 xmllint
并要求它解析带有标志 --html
的 HTML 文件,并提供来自 top-level 的 xpath
查询以获取节点任您选择。
例如要获取 post id post43
的内容,请使用类似
xmllint --html --xpath \
"//html/body/div[@id='main']/div[@id='bloglisting']/article[@id='post43']" html
如果在您的机器上编译的 xmllint
不理解一些最近的 (HTML5) 标签,如 <article>
或 <nav>
,通过添加 2>/dev/null
在命令的末尾。
如果您只想获取 <article>
中的内容而没有标签本身,请通过管道将结果传递给 sed
来删除第一行和最后一行,如下所示。
xmllint --html --xpath \
"//html/body/div[@id='main']/div[@id='bloglisting']/article[@id='post43']" html 2>/dev/null |
sed '1d; $d'
要为 post-id 使用变量,请定义一个 shell 变量并在 xpath
查询
postID="post43"
xmllint --html --xpath \
"//html/body/div[@id='main']/div[@id='bloglisting']/article[@id='"$postID"']" html 2>/dev/null |
sed '1d; $d'