| @雑談

福岡県水産海洋技術センターから見る脊振山

年が明けてからやるのはどうかと思うが、タイミングがなかったので今さらながら 2022 年のふりかえり。

ランニング

2022 年はよく走った。これまでも何度か走ってると書いていたが、ちゃんとグラフにしてみると 2022 年の 8 月までは大して走っておらず、 2022 年の 9 月から本腰を入れて走るようになったようだ。

オレンジ色の線が 2022 年のもので、9 月から傾きが急になっている。 9 月は月間 110km 走った。月間 100km はフルマラソンに出られる基準のようなのでこの頃は調子こいていた。

ランニングの頻度を上げるのに役立ったのが計画表だった。それまで漫然と走っていたが、漫然と走っていると月間 100km も走れないことに気がついた。自分は一回 5km 走っているが、それを気が向いたときに週 2, 3 度やるだけだと月間 50km くらいにしかならない。きちんとランニングした日と距離を確認していかないと目標には辿り着かない。ログは Apple Watch で取得しているが、統計データとしては見られない。なので HealthFit というアプリを使っているが、 HealthFit では目標設定ができないので Numbers でシートを作って管理することにした。これは元はてなのディレクターの二宮さんの記事の真似。

こちらが年間の週次のランニング計画。

年間ランニング計画

こちらが月間の日次のランニング計画。

月間ランニング計画

月間のシートに日次の目標と実績値を入れると、年間の週次のシートに自動反映される仕組みになってる。これによって自分は一週間に何 km 走る予定で現在目標に対してどのくらい達成しているのかを確認できるようになる。

37signals の本を読んで、計画を立てるのはアホだ、数値目標なんて意味がない、未来を先読みすることはできない、という発想に影響されて計画を立てたりするのは何となく良い印象を持っていなかったけど、月間何キロくらい走りたいとか、ベンチマークとなる具体的な数値目標がないとなかなか実績は積み上がっていかないと思う。もちろんまだ走ったことがない状態でいきなり月間 100km のような目標を立てるのは愚かだと思うが、そこそこ走れるようになってきたら(自分の力がわかるようになってきたら)計画を立てたり数値目標を設定したりするのは悪くないことだと思う。

9 月にがむしゃらに走ったおかげか、最近は走るペースが一段速くなっていて、 1km を 5 分台で走れるようになってきた。今年はちょっと色気を出して初心者向けのトレランの大会に出てみようかと思ってる。

登山

4 月に脊振山系全山縦走、 11 月に九州脊梁に行った。夏に北アルプスを予定していたが、ちょうどコロナにかかって行くことができなかった。何にせよ最近は山に登るのよりも近所を走る方が楽しいので山への足が遠のいた一年だった。登山時の体力作りで走り始めたのに本末転倒している。

仕事

一昨年は結構でかい成果を出せたが 2022 年はぱっとしない一年だった。反省したい。

生活

iPhone を買い換えて 11 から 14 Pro になった。カメラが三つになって望遠の写真を撮れるようになったのが便利。 Dynamic Island も便利。タイマーかけてるときに常に Dynamic Island で残り時間を確認できるのは相当便利。 164800 円払ってよかった( 36 回ローン)。

サウナにハマってぼちぼち行っていた。サウナーの人たちのように一週間に何回も通うというほどではないが、金曜日の仕事帰りにサウナまで走って行ってサウナに入って帰るというのを何回かやった。花金感が出て良い。

2020 年に車を買い換えたがあまりドライブしてない。アメ車なので燃費が悪い、コロナなので出かけづらい、などいろいろあるが、せっかく車を買い換えたのに使わないで置物になってるのはもったいないので有効活用したい。

そういえば 2022 年は YouTube をよく見た。 YouTube Premium に入ったので広告が表示されなくなり、邪魔が入ることなくとてもなめらかに動画を視聴できるようになった。 Netflix はあまり見ていなかったので解約し、 YouTube で素人が上げる動画をよく見た。ストーリーのない、ただ料理をしているだけとか、ただ穴蔵を掘っているだけの 15 分くらいの動画を見るのがちょうどよい。 Netflix の動画は長いし、ことあるごとに金、暴力、セックスを意識させられるので見るのがきつい。こってりしすぎている。

ブログ

Tantivy を導入して全文検索できるようにした。検索も見た目を変えてインクリメンタルサーチできるようにしたりした。年に一回くらいはバズる記事を書きたいが、 2022 年は不作だった。反省したい。

総括

仕事や生活、ブログは本当にぱっとしなかった。その代わり走ることを頑張っているのかも知れない。ランニングや登山は、大して頑張って生きていないのに走ったり山に登ったりするとめっちゃ頑張ってるかのような錯覚を得られて自己肯定感が高まる。仕事などでもちゃんと成果を出しつつ走ったりできたら良いのだけど自分の場合は逃避になってるような気がする。しかし走るのをやめたら仕事で成果を出せるかというとそうでもないし、遺伝的に糖尿病のリスクがあるので発症しないように死ぬまで走り続けるしかない。 2023 年は運動しつつ仕事やブログ書きでも一定の成果を上げたい。あともうちょいサウナに行きたい

| @技術/プログラミング

ブログのアクセス数を集計してランキング(人気記事一覧)を表示している。

シェルスクリプトでログを集計して頑張っているが、ボットからのアクセスを除外など結構やることが複雑化してきた。また最近は主にロシア方面からのスパマーによるアクセスが多く、全然いま読まれる要素がない記事がランキング上位に入ったりしてた。スパマーは以下の 2 記事が好きなようだ。

Google Analytics でアクセス数を見るとこれらの記事は上位に入ってこないので、 Google はちゃんとスパマーからのアクセスを除外しているのだろう。

というわけで Google Analytics の API からアクセス数を取得してみることにした。

しかし調べてみた感じ、あまり情報がない。 Google の公式ドキュメントは Java とPython と Go と PHP と JavaScript のサンプルしかない。

Google が公開している Ruby のライブラリはあるが、ドキュメントがえらく貧弱で勘で使うしかない。

使い方を紹介しているブログもあるにはあるが、この Ruby 製のライブラリはアルファ版とベータ版しかなくてころころ仕様が変わるようだ。先人の情報通りに動かしてみたら全然動かなかった。

API の仕様や上述のライブラリのコードを読みつつ以下のようなコードを書いたところいい感じに使えるようになった。 Ruby で Google Analytics の API にアクセスしたいと思っている人には参考になるんじゃないかと思う。

↑のコードでは metrics は screenPageViewstotalUsers を取得している。 dimension は pagePathpageTitle だ。ほかのが必要であれば変えてあげればよい。これを Rake タスクから呼び出して必要な情報を得るようにしている。

API 呼び出しについては Google が提供している Query Explorer で確認するとよい。

また Analytics API は利用開始前に設定が必要。 Quickstart ページで API を有効化し、 GCP に IAM を作成して credential をダウンロードして Google Analytics 側でこの IAM への API アクセスを許可する必要がある。コード書く前にこの辺でくじけそうになるだろうけど頑張ってほしい。

| @Mac/iPhone

Desktop

コロナ禍によるリモートワークも 2 年以上が経過した。仕事用のパソコンと私用のパソコンの二台を机の上に置かねばならず困っている人も多いんじゃないだろうか。自分は書斎もなく、狭い無印良品の机の上で仕事用の Mac と私物の Mac とをどう配置するかいろいろ試してきたが、一応の結論に辿り着いたのでメモっておく。要点は以下だ。

  • USB スイッチを導入する
  • トラックパッドやキーボードはあえて有線接続する
  • スピーカーへの出力も USB 経由にする

左側に勤務先から貸与されている MacBook Pro 、真ん中に私物の Dell の 23 インチディスプレイ、右側に私物の iMac 5K を配置している。当初はそれぞれキーボードとトラックパッド、マウスなどを配置していたので机の上が狭く悩んでいた。またスピーカー( BOSE の Computer Music Monitor )も一つの Mac にしか接続できず、仕事用 Mac に接続すると仕事中は良い音質で音楽が聴けるが仕事が終わったあとは iMac の内蔵スピーカーで聴くみたいな感じになっていて残念だった。

まず取り組んだのが USB スイッチの導入だ。以下の製品を購入した。

これにより一セットのキーボードとトラックパッドを日中は仕事用 Mac 、夜は私物 Mac という具合に接続を切り替えられるようになった。それまで机の上にキーボード二つ、トラックパッド、マウスがあって狭かったのが仕事でも私用でも同じキーボードとトラックパッドが使えるようになり、机が広々と使えるようになった。なおマジックトラックパッドは Bluetooth 接続ではなく USB スイッチで切り替えるためにあえて USB ケーブルで有線接続している。

USB Switch

次にスピーカーを共用できないかいろいろ調べたみた。 3.5mm ジャックが二つあってスイッチで切り替えられる製品があることを知り導入してみた。これによりスピーカーについても仕事と私用で共用できるようになったが、仕事モードと私用モードを切り替えるときに USB スイッチのボタンとオーディオスイッチのボタンで二回押すのが面倒だった。

その後、 USB DAC を導入した。せっかく買ったのだから仕事中も私用でも USB DAC を通してハイレゾロスレスで音楽を聞きたいと思うようになった。なので 3.5mm ジャック経由で音を出力するのをやめて仕事用 Mac からも私物 Mac からも USB 経由で音を出力し、 USB スイッチを経由するようにした。 USB スイッチから USB DAC につなぐことで、仕事用でも私物 Mac でもハイレゾロスレスで音楽を再生できるようになった。

すべての入出力を USB スイッチを経由するようにしたことにより、キーボード、トラックパッド、スピーカーをすべて仕事用 Mac と私物 Mac で共用できるようになった。切り替えはボタン一発だ。

なおこの環境を構築し終わったあとに macOS Monterey 12.4 がリリースされてユニバーサールコントロールにより隣り合う Mac でキーボードやトラックパッドを共有できるようになったが、結構接続が不安定だしカクつくこともあるので現状の有線接続の USB スイッチによる切り替えで全く不満はない。

私物の iMac 5K が机右側にあり、私用で Mac を触るときに首を少し右側に向けないと行けないのが少しストレスだ。なので L 字形の机を導入して常に机を正面に据えて作業できるようにしてみようとしたが、 FlexiSpot の以下の昇降デスクの購入を検討しているうちにプライムデーセールで売り切れてしまい、いまも顔を右にひねりながらブログを書いている。

この EG1-L を導入することができたら自分の在宅ワーク環境は完成されるなと思っている。楽歌株式会社さん( FlexiSpot の製造元)、良かったら再販売してもらえないでしょうか。できたら昇降範囲を 69cm からにしてもらえると短足胴長のおっさんでも快適に使えて助かります

| @ブログ

グローバルナビゲーション(右上の白い領域)内の検索ボタンを押したら Alfred 風のモーダル検索フォームが開いて、そこにキーワードを入力するとインクリメンタルサーチが実行されて逐次検索結果の記事が表示されるようにした。

これまでだと検索すると Archives ページの絞り込み検索に飛ばすだけだったが、 Archives ページに遷移せずに検索できるようになった。また Archives ページだと時系列順でしか検索結果が表示されないが、インクリメンタルサーチではマッチ度順に関連度の高いものを表示するようにしている。ただし表示するのは上位 10 件だけにして、それ以上は Archives ページで時系列順の検索に飛ばしている。

昔ながらのブログの検索 UI には不満がある。ページネーションで何ページも辿って検索結果を見ていくのは大変だし、大抵並び順が時系列順で自分が最も用事がありそうな記事に辿り着くのに時間がかかる。自分のブログの検索はタイトルのみ表示されればよくて本文のプレビューは不要だし(著者だからタイトルを見ただけでどんな記事なのか大体わかる)、何ページもページネーションせずに一覧でガッと検索結果を見たい。それに結果は時系列順ではなく関連度が高い順に並んでいて欲しい。キーワードを一部だけかすってるような最近の記事が最も関連度が高い記事を差し置いて最上位に表示されるのはいまいちだ。

今回作った Alfred 風インクリメンタルサーチではこれらの問題が解消されていて非常に満足。自分にとって自分のブログが世の中の情報の中で一番参照頻度が高いし、そのブログで効率的に情報を取り出せるのは大切なことだと思う。

| @技術/プログラミング

Rust 製の全文検索システム Tantivy を Ruby から使える Tantiny を導入したことを書いた。

結構手軽に使えるのだがやはり日本語のトークナイズ(形態素解析)ができないのでいまいちなところがあった。 Tantivy には lindera-tantivy というものがあって、 Lindera は kuromoji のポートなので、これを使うと日本語や中国語、韓国語の形態素解析ができる。 Tantiny に導入できないか試してみたが、自分の Rust 力では到底無理だった。

ちなみに関連記事の表示でも日本語の形態素解析は行っている。

MeCab に neologd/mecab-ipadic-neologd を組み合わせてナウな日本語に対応させつつ形態素解析している。

この仕組みを作ってトークナイズは Ruby で自前で行い、 Tantiny および Tantivy にはトークナイズ済みの配列を食わせるだけにした( Tantiny はトークナイズ済みのテキストを受け付けることもできる)。トークナイズを自前で行うことで辞書ファイルで拾いきれないような固有名詞もカバーできる。例えば 山と道 なんかは MeCab と mecab-ipadic-neologd にトークナイズさせると に分割されてしまう。自前のトークナイザーで単語として認識させていている。おかげで「山と道」をちゃんと検索できるようになっている

なお、自前のトークナイザーはこんなコードになっている。

class Tokenizer
  attr_reader :text

  class << self
    def run(text)
      self.new(text).tokenize
    end
  end

  def initialize(text)
    @text = text
  end

  def cleansed_text
    @cleansed_ ||= text.
      gsub(/<.+?>/, '').
      gsub(/!?\[(.+)?\].+?\)/, '\1').
      gsub(%r{(?:```|<code>)(.+?)(?:```|</code>)}m, '\1')
  end

  def words_to_ignore
    @words_to_ignore ||= %w[
      これ こと とき よう そう やつ とこ ところ 用 もの はず みたい たち いま 後 確か 中 気 方
      頃 上 先 点 前 一 内 lt gt ここ なか どこ まま わけ ため 的 それ あと
    ]
  end

  def preserved_words
    @preserved_words ||= %w[
      山と道 ハイキング 縦走 散歩 プログラミング はてブ 鐘撞山 散財 はてなブックマーク はてな
    ]
  end

  def nm
    require 'natto'
    @nm ||= Natto::MeCab.new
  end

  def words
    @words ||= []
  end

  def tokenize
    preserved_words.each do |word|
      words << word if cleansed_text.match?(word)
    end

    nm.parse(cleansed_text) do |n|
      next unless n.feature.match?(/名詞/)
      next if n.feature.match?(/(サ変接続|数)/)
      next if n.surface.match?(/\A([a-z][0-9]|\p{hiragana}|\p{katakana})\Z/i)
      next if words_to_ignore.include?(n.surface)
      words << n.surface
    end

    words
  end
end

preserved_words が手製の辞書だ。 はてなはてブ も辞書登録しておかないと MeCab だとバラバラに分割されてしまって検索できなかった。

難点としては記事更新後に自動でインデックスの更新が行われず、 cron によるバッチ処理でインデックス更新を行っている[1]。なので検索インデックスにデータが反映されるまでにタイムラグがある。 Tantiny でやれれば記事作成・更新時のコールバックとして処理できるのでリアルタイムに変更を検索インデックスに反映させることができるが、個人の日記なのでタイムラグありでも大きな問題にはならない。

本当は Tantiny で lindera-tantivy を使えるようにして Pull Request がカッチョイイのだが、とりあえずは自分は目的が達成できたので満足してしまった。 5 年くらい前から Rust 勉強したいと思っているが、いつまでも経っても Rust を書けるようにはならない。

[1]: mecab-ipadic-neologd を VPS 上でインストールできず(めっちゃメモリを使う)、手元の Mac で Docker コンテナ化して Docker Hub 経由でコンテナイメージを Pull して VPS 上で Docker 経由で動かしている(その辺について書いてる記事: ブログのコンテナ化を試みたけどやめた

| @WWW

以前、以下の記事でこのウェブサイトへのアクセス元 User Agent について書いた。

そのとき Hatena::Russia::Crawler というのが謎だということを書いた。最近のアクセスログを見ても相変わらずこの User Agent からのアクセスが多い。またアクセス頻度も高く、同一の URL に対して何度もアクセスしている。

これはやはりはてなの名を騙った怪しいクローラーなのではないかと思い調べてみた。

まず Hatena::Russia::Crawler という User Agent からのアクセスの IP アドレスを調べてみたところ以下だった。

cat log/access.log | grep 'useragent:Hatena::Russia::Crawler/0.01' | cut -f2 | sort | uniq -c | sort -nr
    434 remote_addr:52.68.0.227
    419 remote_addr:54.249.85.140
    417 remote_addr:54.92.97.59
    379 remote_addr:54.250.227.185

whois してみると AWS で運用されているものであることがわかるが、はてなのものかは断定できない。

もしこの IP からはてなブックマークやはてなアンテナなどの User Agent でのアクセスもあれば Hatena::Russia::Crawler ははてなのクローラーであると断定できるだろう。ということで調べてみたところこんな感じだった。

zcat -f log/access.log* | grep -E 'remote_addr:(52\.68\.0\.227|54\.249\.85\.140|54\.92\.97\.59|54\.250\.227\.185)' | cut -f13,2 | sort | uniq -c | sort -nr
  16687 remote_addr:54.250.227.185      useragent:Hatena::Russia::Crawler/0.01
  16448 remote_addr:54.92.97.59 useragent:Hatena::Russia::Crawler/0.01
  16370 remote_addr:54.249.85.140       useragent:Hatena::Russia::Crawler/0.01
  16272 remote_addr:52.68.0.227 useragent:Hatena::Russia::Crawler/0.01
     73 remote_addr:54.249.85.140       useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     60 remote_addr:54.250.227.185      useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     56 remote_addr:52.68.0.227 useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     50 remote_addr:54.92.97.59 useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     31 remote_addr:54.92.97.59 useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     31 remote_addr:54.250.227.185      useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     31 remote_addr:54.249.85.140       useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     26 remote_addr:52.68.0.227 useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     19 remote_addr:54.92.97.59 useragent:Hatena::Scissors/0.01
     19 remote_addr:54.250.227.185      useragent:Hatena::Scissors/0.01
     16 remote_addr:52.68.0.227 useragent:Hatena::Scissors/0.01
      9 remote_addr:54.249.85.140       useragent:Hatena::Scissors/0.01

なんと、 IP アドレスで検索してはてなのその他のクローラーもヒットしてしまった。つまり Hatena::Russia::Crawler ははてなのクローラーということだ。

ただしググっても一切情報が出てこない。 Hatena::Russia::Crawler で検索してトップヒットするのは自分のブログだ。

改めて Hatena::Russia::Crawler による直近 30 日間のアクセス状況を調べてみるとこんな感じだ。

zcat -f log/access.log* | grep 'useragent:Hatena::Russia::Crawler/0.01' | cut -f5 | sort | uniq -c | sort -nr
  15697 request_uri:/index.atom
   9913 request_uri:/2022/04/20/integrate-charts-category-with-select-boxs
   9373 request_uri:/2022/05/04/reputation-and-interpretation
   8422 request_uri:/2022/05/11/fly-to-kamikochi-from-fukuoka
   7716 request_uri:/2022/05/16/using-tantivy-over-tantiny
   5906 request_uri:/2022/04/17/quit-using-hey
   5139 request_uri:/2021/12/29/thoughts-on-manga-subscription
   1308 request_uri:/2021/12/13/keep-a-stack-books-whether-reading-them-or-not
    787 request_uri:/2022/06/23/each-entry-title-should-be-marked-up-with-h1
    741 request_uri:/2021/12/13/keep-stack-books-whether-reading-them-or-not
    456 request_uri:/2022/06/24/if-you-feel-apple-musics-recommendation-is-awful
    100 request_uri:/2022/06/14/thoughts-on-hatena-bookmark
     46 request_uri:/2015/12/07/thoughts-on-rural-life
     46 request_uri:/2015/12/02/thoughts-on-t-on-t
     46 request_uri:/2015/12/02/thoughts-on-christmas-song
     45 request_uri:/2019/12/02/stop-drinking-outside-frequently
     16 request_uri:/2020/11/08/where-i-went-in-2019
     11 request_uri:/2015/12/05/omm-writer-music-is-nice-to-listen-to-while-writing
      5 request_uri:/2022/05/04/the-golden-maintenance-week
      2 request_uri:/2022/06/24/
      2 request_uri:/2022/06/24

index.atom はフィードの URL なので除外するとして、特定の記事に対して数千回もアクセスがある。 30 日間で 9000 回ということは一日あたり 300 回だ。 1 時間あたり 12.5 回である。何のためにこんなに高頻度でクローリングしているのだろうか。

とここまで調べたところほかの Bot 系アクセスはどうなのかと改めて User Agent 毎のアクセス数を調べてみたらこんな感じだった。

zcat -f log/access.log* | cut -f13 | sort | uniq -c | sort -nr | head -10
 124894 useragent:Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)
  65794 useragent:Hatena::Russia::Crawler/0.01
  58274 useragent:Ruby
  31493 useragent:Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1
  29454 useragent:Mozilla/5.0 (compatible; AhrefsBot/7.0; +http://ahrefs.com/robot/)
  21492 useragent:Tiny Tiny RSS/21.11-7cfc30a (https://tt-rss.org/)
  20351 useragent:Slackbot 1.0 (+https://api.slack.com/robots)
  18765 useragent:Mozilla/5.0 (compatible; SemrushBot/7~bl; +http://www.semrush.com/bot.html)
  18395 useragent:Mozilla/5.0 (compatible; MJ12bot/v1.4.8; http://mj12bot.com/)
  17942 useragent:Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

bingbot からのアクセスの方が Hatena::Russia::Crawler からのアクセスの 2 倍近くあった。ただし bingbot は検索エンジンのクローラーらしく、サイト全体をまんべんなくクローリングするような挙動で、特定の URL に一ヶ月間で数千回アクセスするような感じではない。

zcat -f log/access.log* | grep 'useragent:Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)' | cut -f5 | sort | uniq -c | sort -nr | head -25
    571 request_uri:/robots.txt
    352 request_uri:/
    205 request_uri:/category/misc
    160 request_uri:/2007/01/13/732
    156 request_uri:/2005/10/28/129
    150 request_uri:/2009/03/23/1010
    148 request_uri:/category/music
    146 request_uri:/archives
    144 request_uri:/category/www
    143 request_uri:/2016/07/
    143 request_uri:/2009/08/31/1074
    139 request_uri:/2010/07/05/1140
    138 request_uri:/category/photo
    138 request_uri:/2009/02/
    137 request_uri:/2006/09/09/658
    136 request_uri:/tags/netatmo
    136 request_uri:/2010/07/17/1145
    136 request_uri:/2006/07/23/611
    135 request_uri:/2014/03/
    134 request_uri:/?page=32
    134 request_uri:/2007/02/09/747
    133 request_uri:/category/shopping
    133 request_uri:/2021/07/26/how-to-get-to-kamikochi-from-fukuoka
    133 request_uri:/2011/11/03/finally-got-hhkpro2
    132 request_uri:/2006/01/

Hatena::Russia::Crawler は同一 URL に数千回もアクセスして何をしているのだろう? 謎は深まるばかりだ。

| @ブログ

最初にブログを作ったときからウェブサイトのタイトル(やロゴ画像)が h1 で、記事タイトルが h2 という見出しレベルで HTML を書いていた。しかし最近では、記事パーマリンクのページではサイトのタイトルなどには見出しレベルを設定せず、記事タイトルに h1 を当てている場合が多いようだ。なのでこのサイトでも記事タイトルを h1 とするように変えた。本文中の見出しレベルも h3 スタートだったのを h2 スタートに変えた。

伝統的なブログはインデックスページと記事パーマリンクページで HTML テンプレートを共通化している。なのでインデックスページに記事一覧を表示して h1 タグが並ぶとまずいということで記事タイトルは h2 から、という作りになってるような気がする。このサイトはインデックスページとパーマリンクページでのテンプレート共有化をほぼほぼやめたので、インデックスページとパーマリンクページで記事タイトルの見出しレベルを柔軟に変更している。

サイトの作り手からするとウェブサイトのタイトルこそが最も重要な要素でタイトルロゴなどを h1 でマークアップしたくなるのだが、読み手は Twitter やはてブから飛んできて刹那的に記事を消費し、インデックスページなんかには見向きもせずに去って行くだけだ。個別記事のタイトルこそ重要なのだ。

追記

r7kamura さんからこういうコメントをもらってこういう風に返信した。

HTML5 が出てきたとき、個人的には何かめんどくさいなぁとしか思ってなかったし、世間は Flash を置き換える近未来技術みたいな評価をしていたと思う。しかし、 <header> タグや <article> タグによって、 HTML の構造化と文書の構造化を分離できるようになったのがセマンティックWeb的なメリットだということに気がついた。つまり <h1> などの見出しルールは <article> タグの中で守られていればよいのだ。

ということに HTML5 が死んでから気がついた。