Bash如何从网页中提取JSON数据?
解决Lazada页面JSON提取的纯Bash方案
我来帮你搞定这个提取JSON的问题!你之前用的grep -Poz命令没成功,大概率是因为多行匹配的逻辑或者边界处理出了问题——grep的-z会把整个输入当成单行处理,加上正向预查的贪婪匹配,很容易漏掉或者错误捕获内容。下面给你几个纯Bash环境下就能运行的可靠方案:
方案1:用sed处理多行匹配
sed对多行文本的处理更灵活,能精准定位app.run(到);之间的内容:
curl -s 'https://www.lazada.co.id/-i160040703-s181911730.html?spm=a2o4j.order_details.details_title.1.52ec6664luQAQs&urlFlag=true&mp=1' | sed -n ' /app.run(/ { s/app.run(// /);/ { s/);$// p b } :loop N /);/ { s/);$// p b } b loop } '
这个脚本的逻辑是:
- 找到包含
app.run(的行,先去掉开头的app.run( - 如果当前行直接包含
);,就去掉结尾并打印 - 如果不包含,就持续读取下一行,直到找到
);,再处理并打印
方案2:用awk实现逐行捕获
awk的状态机模式也能很好处理这种跨多行的内容:
curl -s 'https://www.lazada.co.id/-i160040703-s181911730.html?spm=a2o4j.order_details.details_title.1.52ec6664luQAQs&urlFlag=true&mp=1' | awk ' /app.run(/ { in_json = 1 sub(/app.run(/, "") } in_json { if (/);/) { sub(/);$/, "") print in_json = 0 } else { print } } '
这个脚本会:
- 当遇到
app.run(时,标记进入JSON内容区域,并去掉该行的前缀 - 在标记区域内,逐行输出内容,直到遇到
);,去掉后缀后输出并结束标记
为什么原命令失败?
你的grep -Poz '(?<=app.run\()(.*\n)*.*(?=\);)'有两个主要问题:
-z参数会把所有换行符换成空字符,导致.*\n的匹配逻辑失效- 正向预查和贪婪匹配的组合,可能因为页面中存在其他类似
);的字符串,导致匹配到错误的边界
如果提取后想验证JSON格式是否正确,你可以额外用jq工具(很多系统默认安装),比如把结果管道到jq .就能快速检查格式合法性。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

