提问人:Neha 提问时间:9/14/2023 最后编辑:Neha 更新时间:9/17/2023 访问量:151
用于获取 HTML 表格数据的 Bash 脚本
Bash Script To Get HTML Table Data
问:
我有一个网页,里面有一个非常简单的 HTML 表格。该网页的HTML代码如下。HTML 将始终保持不变,只有数据值会更改。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo Page Results</title>
<link rel="stylesheet" href="/static/styles.css">
</head>
<body id="particles">
<div class="container">
<h1>Demo Page Results</h1>
<table>
<tr>
<td>
Examiner:
</td>
<td class="marked">
Person
</td>
</tr>
<tr>
<td>
Qualification:
</td>
<td class="marked">
Teacher
</td>
</tr>
<tr>
<td>
Nation:
</td>
<td class="marked">
Any
</td>
</tr>
</table>
</div>
<script src="/static/jrf.min.js"></script>
<script src="/static/scripts.js"></script>
</body>
</html>
代码的输出如下
演示页面结果
审查员:人
任职资格:教师
国家:任何
我需要使用 bash 脚本来获取表的内容,如下所示
Examiner: Person
Qualification: Teacher
Nation: Any
我正在使用以下 bash 脚本
#!/bin/bash
# URL of the webpage
# containing the HTML
# table
URL="http://thewebpageurl"
# Use curl to fetch the
# HTML content of the
# webpage
HTML=$(curl -s "$URL")
#echo $HTML
# Use grep and sed to
# extract the table
# content
TABLE_HTML=$(echo "$HTML" | grep -o '\<table\[^\>\]\*\>.\*\</table\>' | sed 's/\<\\/table.\*//')
echo $TABLE_HTML
# Use awk to parse and
# print the table data
echo "$TABLE_HTML" | awk -F"\</tr\>" '{ for (i=1; i\<=NF;i++) { sub(/.\*\<td\[^\>\]\*\>/, "", $i); sub(/\<\\/td\>.\*/, "", $i); printf "%s ", $i; } printf "\\n"; }'
但遗憾的是,这并没有显示出任何结果。
请帮助并指导我修复 bash 脚本。 谢谢 尼哈
答:
1赞
Shawn
9/14/2023
#1
您可以在 HTML 模式下使用 XPath 表达式来提取表格单元格的内容,然后将其调整为所需的格式:xmllint
$ xmllint --html --xpath '//div[@class="container"]/table/tr/td/text()' input.html | perl -0777 -pe 's/:\s+/: /g; s/^\s+//mg'
Examiner: Person
Qualification: Teacher
Nation: Any
0赞
dawg
9/14/2023
#2
Ruby 有一个很棒的 XML/HTML 解析器,叫做 Nokogiri。
你可以做这样的事情:
ruby -r nokogiri -e 'Nokogiri::HTML($<.read).at("table").search("tr").
each{ |tr|
cells = tr.search("th, td")
puts cells.map{|cell| cell.text.strip }.join(" ")
}' file
指纹:
Examiner: Person
Qualification: Teacher
Nation: Any
评论
0赞
Neha
9/14/2023
只是添加HTML代码的结构永远不会改变,只有数据值会改变。也请帮助我仅使用 curl、grep、awk/sed 实现所需的输出。
0赞
Neha
9/14/2023
通过一些打击和尝试......我得到了 bash curl -s myurl |awk '/<table>/,/<\/table>/' |sed -n '/<tr>/,/<\/tr>/p' |sed -e 's/<[^>]*>//g' |tr -d ' \n' 但输出是包含所有表数据值的单行,即 Examiner:PersonQualification:TeacherNation:Any 如何在每行后添加一个 #?例如:Examiner:Person#Qualification:Teacher#Nation:Any
0赞
Ed Morton
9/15/2023
#3
假设您的 HTML 格式永远不会改变,如您所说,然后使用任何 POSIX awk:
$ cat tst.sh
#!/usr/bin/env bash
awk '
{ gsub(/^[[:space:]]+|[[:space:]]+$/,"") }
$0 == "</td>" { inTag=inVal=0 }
inTag { tag = $0 }
inVal { print tag, $0 }
$0 == "<td>" { inTag=1 }
$0 == "<td class=\"marked\">" { inVal=1 }
' "${@:--}"
$ ./tst.sh file
Examiner: Person
Qualification: Teacher
Nation: Any
如果您真的希望在每个输出行后面有一个空行,如问题中的预期输出所示,则只需更改为 .print tag, $0
print tag, $0 ORS
评论
0赞
Neha
9/15/2023
非常感谢,代码运行良好。我必须更改什么才能在一行中获得输出,如 Examiner:Person#Qualification:Teacher#Nation:Any
0赞
Ed Morton
9/15/2023
别客气。强烈建议不要在此表格上提出变色龙问题,因此,如果您无法弄清楚,请提出一个新问题。同时,请参阅 stackoverflow.com/help/someone-answers,了解此问题的下一步操作。
0赞
ufopilot
9/15/2023
#4
$ awk '!/^$|</{i++; printf "%s %s", $1, (i%2==0 ? "\n": "")}' file
Examiner: Person
Qualification: Teacher
Nation: Any
0赞
potong
9/15/2023
#5
这可能对你有用(xidel 版本 0.9.8,GNU paste 和 sed):
xidel file -se '//td' | paste -d' ' - -
或者将所有内容放在一行上,以以下方式分隔:#
xidel file -se '//td' | sed 'N;s/\n//' | paste -sd#
上述解决方案也可以完全用xidel(感谢Reino)复制,因为:
xidel file -se '//tr/normalize-space()'
和:
xidel file -se 'replace(join(//tr/normalize-space(),"#")," ","")'
评论
0赞
Reino
9/16/2023
无需其他工具:.此外,您的解决方案不会产生 OP 所需的结果。-e '//tr/normalize-space(td)'
0赞
potong
9/17/2023
@Reino,谢谢,但这也不能重现 OP 所需的结果。但是,这确实等同于我的第一个解决方案。我的第二个是回应 OP 对 Ed Morton 的解决方案提出的第一条评论,只要稍加修改,就可以使用-e '//tr/normalize-space()'
-e 'replace(join(//tr/normalize-space(),"#")," ","")'
评论
awk
逐行处理输入文件(或更具体地说,逐条记录处理,您可以在其中定义记录分隔符)。您不知道 HTML 文件的行结构。例如,同一页面可以写成一个包含所有 HTML 代码的长行。AWK 肯定不适合这项任务。我会在这里谷歌搜索 HTML 解析器。&
&
&
lynx --dump input.html | fgrep :