人生100年!生涯エンジニア人生!

楽しいエンジニア人生!

意外と便利なcurlのwriteoutオプション(http_codeとurl_effectiveは便利過ぎる)

唐突にきた調査依頼

依頼主「ここにあるURLリストで正常にアクセスできると、URLが変わった物をリストアップしてほしい。」
私「はい、すぐに!お?10万件?スクリプトをサクッとやりますが、量が多いので実行に1日ぐらいかかります。」

できた物

#!/bin/bash

USER_AGENT='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/601.1.39 (KHTML, like Gecko) Version/10.1.2 Safari/601.1.39'

cat ./url.txt | while read old_url
do
  code=`curl -A '"{$USER_AGENT}"' -s -o /dev/null -w '%{http_code}' ${old_url}`
  if [ `echo "${code}" | grep '30'` ]; then
    new_url=`curl -A '"{$USER_AGENT}"' -sL -o /dev/null -w '%{url_effective}' ${old_url}`
    printf '"%s","%s"\n' "${new_url}" "${old_url}"
  elif  [ "${code}" = '200' ]; then
    printf '"%s",""\n' "${old_url}"
 else
    printf '"%s","error url"\n' "${old_url}"
  fi
done

説明

  1. url.txtを読み込んで、whileループで回す。
  2. curlのsilentオプションで、outputオプションは/dev/nullで捨てて、writeoutオプションのhttp_codeでHTTPステータスコードを取得する。
  3. HTTPステータスコード300系ならば、再度curlのsilentオプションで、outputオプションは/dev/nullで捨てて、locationオプションを使って最終的にアクセスしたURLに遷移させ、writeoutオプションのurl_effectiveで遷移したURLを取得し、そのURLと元のURLを表示する。
  4. HTTPステータスコードで200ならば、URLをそのまま表示する。

便利なwriteoutオプション

curlのwriteoutオプションはときどき追加があります、そのためcurltool_writeout.cファイルは時々見ると新たな発見があったりします。
github.com

余談ですが、writeoutオプションには、みんなが大好きなjsonというのもあり、サイトを見るときに指定して意味なく情報を見るのが楽しいです。

実行コマンドです。

curl -s -o /dev/null -w '%{json}' https://www.google.co.jp/ | jq

実行結果です。

{
  "url_effective": "https://www.google.co.jp/",
  "http_code": 200,
  "response_code": 200,
  "http_connect": 0,
  "time_total": 0.220751,
  "time_namelookup": 0.002085,
  "time_connect": 0.012867,
  "time_appconnect": 0.138509,
  "time_pretransfer": 0.138608,
  "time_starttransfer": 0.218738,
  "size_header": 938,
  "size_request": 80,
  "size_download": 12052,
  "size_upload": 0,
  "speed_download": 54781,
  "speed_upload": 0,
  "content_type": "text/html; charset=Shift_JIS",
  "num_connects": 1,
  "time_redirect": 0,
  "num_redirects": 0,
  "ssl_verify_result": 0,
  "proxy_ssl_verify_result": 0,
  "filename_effective": "/dev/null",
  "remote_ip": "2404:6800:4004:80d::2003",
  "remote_port": 443,
  "local_ip": "にゃ~ん",
  "local_port": にゃ~ん,
  "http_version": "1.1",
  "scheme": "HTTPS"
}

あれ?Googleのサイトでcontent_typeが懐かしのShift_JISだ!?
"content_type": "text/html; charset=Shift_JIS"
こんなcontent_typeを返すのは変だな、よし!試しにUser Agentを付加してやってみよう!

curl -A 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/601.1.39 (KHTML, like Gecko) Version/10.1.2 Safari/601.1.3
9' -s -o /dev/null -w '%{json}' https://www.google.co.jp/ | jq

実行結果です。

{
  "url_effective": "https://www.google.co.jp/",
  "http_code": 200,
  "response_code": 200,
  "http_connect": 0,
  "time_total": 0.324704,
  "time_namelookup": 0.004633,
  "time_connect": 0.015616,
  "time_appconnect": 0.168842,
  "time_pretransfer": 0.168961,
  "time_starttransfer": 0.280845,
  "size_header": 1017,
  "size_request": 186,
  "size_download": 188613,
  "size_upload": 0,
  "speed_download": 582138,
  "speed_upload": 0,
  "content_type": "text/html; charset=UTF-8",
  "num_connects": 1,
  "time_redirect": 0,
  "num_redirects": 0,
  "ssl_verify_result": 0,
  "proxy_ssl_verify_result": 0,
  "filename_effective": "/dev/null",
  "remote_ip": "2404:6800:4004:80b::2003",
  "remote_port": 443,
  "local_ip": "にゃ~ん",
  "local_port": にゃ~ん,
  "http_version": "1.1",
  "scheme": "HTTPS"
}

変わった!content_typeUTF-8になりました。
"content_type": "text/html; charset=UTF-8"

これは私の推測ですが、Googleの日本サイトはガラケー全盛期に登場しているので、そのときの名残りかな?と思います。
こういう色々な発見があるのでcurlは楽しいです。