xmllint で HTML 内の任意の値を取り出す

サクッと shell script で HTML の中の何かを取り出したい時があります。 そんな時に使えるのが xmllint. しっかりやるなら python の Beautiful Soup を使ったりしますが、本当に簡単なことを簡単にやりたい場合に xmllint でサクッとやったメモ。

試した環境は次の通り。

$ sw_vers
ProductName:            macOS
ProductVersion:         13.1
BuildVersion:           22C65
$ /usr/bin/xmllint --version
/usr/bin/xmllint: using libxml version 20913
   compiled with: Threads Tree Output Push Reader Patterns Writer SAXv1 FTP HTTP DTDValid HTML Legacy C14N Catalog XPath XPointer XInclude ICU ISO8859X Unicode Regexps Automata Schemas Schematron Modules Debug Zlib

FORM の HTML が返ってくるのでそこから hidden で埋め込まれている input の value や送信先 (action) を取り出したかった。

次のような HTML (example.html) があったとする

<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>タイトル</title>
  </head>
  <body>
    <form method="post" id="myform" action="https://httpbin.org/anything">
    <input type="hidden" name="item1" value="apple">
    <input type="hidden" name="item2" value="banana">
    <button type="submit">submit</button>
    </form>
  </body>
</html>

item1value を取得したい場合にどうするか

$ xmllint --html --xpath "string(//input[@name='item1']/@value)" example.html
apple

value の中身の apple が取得きた。

string() で囲まなかった場合は value="apple" となる。

$ xmllint --html --xpath "//input[@name='item1']/@value" example.html
 value="apple"

さらに @value も外すとこんな感じ。

$ xmllint --html --xpath "//input[@name='item1']" example.html
<input type="hidden" name="item1" value="apple"/>

では title の値 (<title></title> で囲まれた中身) が欲しい場合はどうするか。 text() を指定する。

$ xmllint --html --xpath "//title/text()" example.html
タイトル

text() を付けずに次の様にすると <title>myform</title> が出力される。

$ xmllint --html --xpath "//title" example.html
<title>タイトル</title>

あ、そうそう、form の action は次のようにする。

$ xmllint --html --xpath "string(//form[@id='myform']/@action)" example.html
https://httpbin.org/anything
Built with Hugo
テーマ StackJimmy によって設計されています。