bash中的xpath解析表
我有一个html表,我想用bash解析它 (注意:我使用了R来实现这一点,但我想尝试在bash中轻松地与另一个shell脚本集成) 可从以下url获取该表: 通过查看源代码-特定表的xpath参考是:bash中的xpath解析表,bash,csv,xpath,xmllint,Bash,Csv,Xpath,Xmllint,我有一个html表,我想用bash解析它 (注意:我使用了R来实现这一点,但我想尝试在bash中轻松地与另一个shell脚本集成) 可从以下url获取该表: 通过查看源代码-特定表的xpath参考是: //*[@id="ctl03_DesktopThreePanes1_ThreePanes_ctl01_MDlisting"] 如何直接从bash将该表解析为csv文件 我尝试了以下方法: curl "http://faostat.fao.org/site/384/default.aspx" |
//*[@id="ctl03_DesktopThreePanes1_ThreePanes_ctl01_MDlisting"]
如何直接从bash将该表解析为csv文件
我尝试了以下方法:
curl "http://faostat.fao.org/site/384/default.aspx" | xpath '//*[@id="ctl03_DesktopThreePanes1_ThreePanes_ctl01_MDlisting"]' > test.txt
这只返回test.txt的空白文本
有人能帮我在bash中使用xpath解析出有效的html表并创建一个CSV文件吗
感谢您的帮助。/*[@id=“ctl03\u DesktopThreePanes1\u ThreePanes\u ctl01\u MDlisting”]/tr
(也就是说,将/tr
附加到您问题中的XPath表达式后)将只获取每一行,并跳过表
包装器(您不需要在输出中对其做任何操作)
然后,您还需要通过sed
或perl
或其他方式来传递xmllint--xpath
输出:
示例:perl版本
wget -q -O - "http://faostat.fao.org/site/384/default.aspx" \
| xmllint --html \
--xpath '//*[@id="ctl03_DesktopThreePanes1_ThreePanes_ctl01_MDlisting"]/*' - \
2>/dev/null \
| perl -pe 's/<tr[^>]+>//' \
| perl -pe 's/<\/tr>//' \
| perl -pe 's/^\s+<t[dh][^>]*>//' \
| perl -pe 's/<\/t[dh]><t[dh][^>]*>/|/g' \
| perl -pe 's/<\/t[dh]>//' \
| grep -v '^\s*$'
wget -q -O - "http://faostat.fao.org/site/384/default.aspx" \
| xmllint --html \
--xpath '//*[@id="ctl03_DesktopThreePanes1_ThreePanes_ctl01_MDlisting"]/*' - \
2>/dev/null \
| sed -E 's/<tr[^>]+>//' \
| sed -E 's/<\/tr>//' \
| sed -E 's/^[[:space:]]+<t[dh][^>]*>//' \
| sed -E 's/<\/t[dh]><t[dh][^>]*>/|/g' \
| sed -E 's/<\/t[dh]>//' \
| grep -v '^\s*$'
使用
列
和colrm
命令格式化输出
如果希望在控制台中读取结果的打印/格式化列/表视图并滚动/翻页,请将输出进一步导入列
和colrm
命令,如下所示:
wget -q -O - "http://faostat.fao.org/site/384/default.aspx" \
| xmllint --html \
--xpath '//*[@id="ctl03_DesktopThreePanes1_ThreePanes_ctl01_MDlisting"]/*' - \
2>/dev/null \
| sed -E 's/<tr[^>]+>//' \
| sed -E 's/<\/tr>//' \
| sed -E 's/^[[:space:]]+<t[dh][^>]*>//' \
| sed -E 's/<\/t[dh]><t[dh][^>]*>/|/g' \
| sed -E 's/<\/t[dh]>//' \
| grep -v '^\s*$' \
| column -t -s '|' \
| colrm 14 21 | colrm 20 28 | colrm 63 95 | colrm 80
或者,您可以使用cut
命令而不是colrm
来获得相同的格式
如何生成真正的CSV 如果您确实想要真正的CSV,而不是像上面那样漂亮的打印/格式化输出,那么您还必须在字段周围发出引号,并在字段内转义CSV现有引号;像这样:
wget -q -O - "http://faostat.fao.org/site/384/default.aspx" \
| xmllint --html \
--xpath '//*[@id="ctl03_DesktopThreePanes1_ThreePanes_ctl01_MDlisting"]/*' - \
2>/dev/null \
| sed -E 's/<tr[^>]+>//' \
| sed -E 's/<\/tr>//' \
| sed -E 's/^[[:space:]]+<t[dh][^>]*>//' \
| sed -E 's/<\/t[dh]><t[dh][^>]*>/|/g' \
| sed -E 's/<\/t[dh]>//' \
| grep -v '^\s*$' \
| column -t -s '|' \
| colrm 14 21 | colrm 20 28 | colrm 63 95 | colrm 80
示例:真实CSV输出
wget -q -O - "http://faostat.fao.org/site/384/default.aspx" \
| xmllint --html \
--xpath '//*[@id="ctl03_DesktopThreePanes1_ThreePanes_ctl01_MDlisting"]/tr' - \
| sed -E 's/"/""/g' \
| sed -E 's/<tr[^>]+>//' \
| sed -E 's/<\/tr>//' \
| sed -E 's/^[[:space:]]+<t[dh][^>]*>/"/' \
| sed -E 's/<\/t[dh]><t[dh][^>]*>/","/g' \
| sed -E 's/<\/t[dh]>/"/' \
| grep -v '^\s*$'
因此,上面代码片段的sed-E的/“/”“/g”
部分就是这样做的
上述示例的CSV输出
"Group Name","Item FAO Code","Item HS+ Code","Item Name ","Definition"
"Crops","800","5304_c","Agave fibres nes","Including inter alia: Haiti hemp…"
"Crops","221","0802.11_a","Almonds, with shell","Prunus amygdalus; P. communis…"
"Crops","711","0909","Anise, badian, fennel, coriander","Include: anise…"
免责声明:您应该避免对HTML/XML进行基于regexp的处理 (强制性免责声明)综上所述,许多人会告诉你基于regexp的HTML/XML处理很难处理,而且很容易出错,所以请谨慎使用上述方法(如果有的话) 如果您有时间做对了,那么您应该做的是:而不是使用一个好的Web抓取库,或者使用Python+
lxml
来实际处理计算XPath表达式返回的结果(而不是字符串化结果),或者使用xsltproc
或其他一些XSLT引擎
Group Name Item FAO Code Item HS+ Code Item Name Definition
Crops 800 5304_c Agave fib Including int
Crops 221 0802.11_a Almonds, Prunus amygda
Crops 711 0909 Anise, ba Include: anis
Crops 515 0808.10_a Apples Malus pumila;
Crops 526 0809.10_a Apricots Prunus armeni
…
但是,您只需要从命令行中获得一些快速、干净的东西,上面的工作就可以完成了。
但是,它很脆弱,因此如果输出的某些部分以某种意外的方式被破坏,请不要感到震惊。如果您希望HTML/XML具有健壮性,请不要使用基于regexp的方法。我设法做到了以下几点:
wget-q-O-http://faostat.fao.org/site/384/default.aspx“| xmllint--html--xpath'/*[@id=”ctl03_DesktopThreePanes1_ThreePanes_ctl01_MDlisting“]'-2>/dev/null>test.txt
但这不会提供CSV输出。有什么办法吗?
"Group Name","Item FAO Code","Item HS+ Code","Item Name ","Definition"
"Crops","800","5304_c","Agave fibres nes","Including inter alia: Haiti hemp…"
"Crops","221","0802.11_a","Almonds, with shell","Prunus amygdalus; P. communis…"
"Crops","711","0909","Anise, badian, fennel, coriander","Include: anise…"