Refactoring English: Month 20

Michael Lynch

Refactoring English:20ヶ月目

原文は Michael Lynch により に公開されました。 このブログを購読する

一言でまとめると

スクレイパーボットと戦いながら、書籍の売上を3倍に。

初めての方へ

こんにちは、マイケルです。ソフトウェア開発者で、小さなインディーテックビジネスをいくつか運営しています。現在はRefactoring English: Effective Writing for Software Developersという本を執筆中です。

毎月、こんな感じの振り返りを公開して、本の進捗や仕事全体の状況を共有しています。

ハイライト

  • 7月の書籍の売上は、すでに好調だった6月の3倍になりました。
  • 世界一間抜けなスクレイパーボットと戦っています。
  • AIを使ってマルチプレイヤーのブラウザゲームを作っています。

目標の自己評価

毎月初めに、達成したいことを宣言しています。結果は次のとおりでした:

『Refactoring English』について話すために5つのポッドキャストに売り込む

  • 結果:1つにしか売り込みませんでした
  • 評価:D

Talking Postgresへのピッチにかなり時間をかけたのですが、気づいたらホストへの連絡手段がLinkedInしかありませんでした。LinkedInでメッセージを送りましたが、返事はありませんでした。The TMPDIR Podcastにゲスト出演はしましたが、こちらは自分から売り込む前にお声がけいただいたので、カウントできません。

Refactoring Englishのウェブサイトにユニーク読者3万人を集める

  • 結果:サイトのユニーク読者は23,800人でした
  • 評価:B

内心ではこの目標を「Hacker Newsのフロントページに1本載せること」だと考えていたのですが、実際に載ったのに3万人には届きませんでした。

アーリーアクセスを終了し、本の正式版1.0をリリースする

  • 結果:まだ1.0リリースには至っていません
  • 評価:D

読者からのフィードバックへの対応に予想以上に時間がかかってしまいました。フィードバックアプリ自体はうまく機能しているのですが、その分、予測しづらい新たな作業が次々と生まれています。

Refactoring Englishの指標

指標2026年6月2026年7月変化
ユニーク訪問者数17,52323,817+6,294 (+36%)
予約販売による収益$1,441.86$3,908.80+$2,466.94 (+171%)

6月はKickstarter以来2番目に売上の良い月でしたが、7月の売上はその6月の3倍になりました。

売上が急増した主な理由は、アーリーアクセス割引を終了したことです。7月13日に、7月20日でアーリーアクセス価格を終了し、価格を30ドルから49ドルに値上げすると告知しました。

7月20日に売上が急増し、その後売上が落ち着いたことを示すグラフ

セール最終日には、「Why I Stopped ‘Creating Content,’」というブログ記事を公開したところ、Hacker Newsのフロントページに掲載されました。さらに、Hacker News風でよりインディーかつテック色の薄いサイトであるbubbles.townでもその日のトップ投稿になりました。

セール最終日には売上が大きく跳ね上がり、その日だけで1,000ドル以上を売り上げました。

価格を49ドルに上げると、予想通り売上は急速に落ち込みました。正式な1.0リリースができたら、価格設定をもっと試していくつもりです。

世界一間抜けなスクレイパーボットと戦っている

月曜日にブログ記事を公開して訪問者が大きく増えました。そして火曜日には、さらに大きな急増がありました:

訪問者の急増を見て、有名なブロガーがリンクしてくれたのかと思いましたが、よく考えるとボットに違いないと気づきました。

訪問者はみなHacker News Popularity Contestに来ていました。以前にも、ブロガーがコンテストでの自分の順位について書いて私のツールにリンクし、訪問者が急増したことはありましたが、今回のような規模や持続的な波は初めてでした。

2回目のスパイクを見たときは、「今週は絶好調だ!」と思いました。妻にそのことを話していたとき、はっと気づいたのです:

今日また5万人も訪問者が来たよ!どこから来てるのかもわからない。誰かがツイートしたのかな。

うーん、でもツイートならリファラーにTwitterって出るはずだよね。

あ……ボットだ。

そしてログを確認すると、すべてのリクエストがまったく同じブラウザのユーザーエージェントを使っていました:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36

これはChrome 125、2年以上前のブラウザバージョンです。この古いバージョンのおかげでボットを簡単に特定できました。私のブログを読むような人が、今さらこんな古いブラウザを使っている可能性は低いからです。

スクレイパーはコンテストのトップページを繰り返し読み込み、そこにあるリンクを片っ端からクリックし続けているようでした。そこでちょっと小細工をしてみました。Bunnyにリライトスクリプトを仕込み、ユーザーエージェントをチェックして、スクレイパーだったら偽のレスポンスを返すようにしたのです。3,000件以上のリンクを含むページを生成する代わりに、リンクが3つしかないページを返すようにしました。

なぜか、この偽装はうまくいきませんでした。おそらくスクレイパーはすでにURLのフルセットをデータベースに登録済みで、ホームページから隠しても意味がなかったのでしょう。

レート制限も試しましたが、Bunnyがサポートする最低制限は1 KB/sで、アプリのデータのほとんどは数KBのファイルに収まっています。スクレイパーは100ほどの異なるIPブロックを使い回していたので、IPごとのスロットリングもできませんでした。

最終的に、IPレンジでブロックすることにしました。Bunnyのログを漁って特定のユーザーエージェントを探し、攻撃に関連するIPをすべて集めるツールを、勢いで(vibecodingで)作りました。それはうまくいったのですが、1週間後に今度は別のIP群と、少しだけ新しいユーザーエージェントで攻撃が再開したので、スクリプトを再実行してブロック対象のIPリストを更新しました。今のところそれでうまくいっているようです。

この攻撃で一番奇妙なのは、ボットがブロックされてもまったく気にしないことです。平然とサーバーを叩き続けます。「TCPレベルで2週間も100%ブロックされているリクエストに、わざわざ計算資源や帯域を無駄にするのはやめよう」と考えそうなものですが、どうやら彼らは気にしないようです。

攻撃者のIPをブロックしても、彼らは叩き続けます。

攻撃が始まった日にNetlifyのサポートに連絡しましたが、まったく役に立ちませんでした。返事が来るまで1週間待たされました。最初の返事は存在しない設定を変更しろという内容だったので、おそらくAIが生成したものでしょう。2回目の返事はより人間っぽかったですが、要するに「返事に2週間かかった間にあなたが問題を解決したようですね、もうやることはありません!」というものでした。幸い、頼んだら55ドルの超過料金は返金してもらえました。

静的サイトはどこでホストすべきか

私はすべての静的サイトをNetlifyでホストしていますが、どんどん質が落ちてきています。今回のスクレイパーボット攻撃に対する完全な無関心ぶりが、もっと積極的に対応してくれるベンダーに乗り換えようと決意させました。

答えは明らかに「Cloudflare」なのですが、インターネットのインフラがCloudflareに集中しすぎているのが気になるので、これ以上集中させたくありません。

VPSやVPS + BunnyをCDNとして使うことも考えましたが、Hacker Newsのフロントページに載った日にVPSがクラッシュしたりBunnyのキャッシュ設定を間違えたりしてサイトが落ちるのは避けたいです。お金を払って、誰かにサイトを常時稼働させておいてもらいたいのです。

  • Surge
    • 長所
      • 静的ホスティングに特化しており、まさに求めているもの
      • 帯域幅が無制限なので、スクレイパーボット攻撃のコストを向こうが負担してくれる
    • 短所
      • (たぶん)1人で運営しているため、障害リスクが高い
      • 管理はすべてターミナルアプリ経由で、ウェブアプリがない
      • 多要素認証に対応していないようだが、対応に向けて作業中のようだ
      • アップロード時に変更されたファイルだけを同期するrsyncのような仕組みではなく、すべてのファイルを無条件にアップロードするため、少しずつしか変わらない大規模なサイトでは手間がかかる
  • statichost
    • 長所
      • 1人で運営しているため、カスタマーサポートが迅速かつ丁寧
      • 余計な複雑さがなく、主に静的ホスティングに特化している
    • 短所
      • 1人で運営しているため、障害リスクが高い
      • アップロード時に変更されたファイルだけを同期するrsyncのような仕組みではなく、すべてのファイルを無条件にアップロードするため、少しずつしか変わらない大規模なサイトでは手間がかかる
      • ボットスクレイパー対策が含まれていない
      • サイトのビルドとホスティングがセットになっているが、ホスティングだけが欲しい
      • 大きな売りがEU中心であることだが、自分は米国在住だ
  • Vercel
    • 長所
      • DDoSやスクレイパーボットを防ぐと謳っている
      • rsync方式のアップロードに対応していると思う
    • 短所
      • 巨大で複雑なサービス
      • Netlifyよりましな対応をしてくれると信じる理由がない
  • Bunny CDNの上に自前で構築する
    • これも検討したが、Bunny上で差分アップロードやアトミックデプロイを実装するのはそれ自体が複雑なプロジェクトになってしまう

Mikeville:未完成のマルチプレイヤーブラウザゲーム

小さなクラウドサーバーを試しているところですが、CPUが4コア、メモリが8GBあり、ほとんどアイドル状態です。手元に余裕のあるまともなサーバーがあるなら、友達のためにホストするとしたら何が楽しいでしょうか?

何かゲームはどうだろう?ValheimARKのようなセルフホストできるゲームも見かけますが、あれは他のプレイヤーが同時にいないと楽しくないようです。

数ヶ月に一度しかゲームをしない自分としては、他の人が同時にいれば一緒に楽しめて、いなくても不在の間に何が起きたかを見るのが楽しいものが欲しいです。イメージしているのは、友達と共同でビーチハウスを所有していて、時々一緒にバカンスを過ごすけど、別々に訪れたときはお互いにメモや贈り物を残しておくような感覚です。

問題は、このビーチハウスのような感覚というコンセプトを、ゲームとして具体的な形にする方法が思いつかないことです。

今のところ、勢いで作る(vibecodingの)ゲーム開発がどんな感じか試しながら、何が楽しいかを探っているところです。このプロトタイプを作るにあたって頭にあったのは、Stardew ValleyとUltima Onlineという、自分が何時間も遊んだ2つのゲームでした。

よければブラウザで遊べます:

今日は少しの間オンラインにいるので、よければ遊びに来てください。ソースコードは、より良いgit forgeが見つかるまでGitLabに置いてあります

気に入ったブログ記事

  • Stripe Just Wants a Number
    • exe.devのブログが好きで、特に小規模なソフトウェアベンダーに影響するソフトウェアの問題について、面白い考え方をしていると思います。自分にはこの恩恵を受けられるほど複雑な課金ロジックはありませんが、原理的には面白いなと思いました。
  • 99% of My Website Traffic Is Bots
    • 今月自分がスクレイパーボットを経験したこともあり、共感できて参考になりました。カスタムイラストも良かったです。
  • I Regret Migrating to Codeberg
    • この1年ほどプロジェクトをGitHubからCodebergに移してきて、有料会員にもなっていますが、今ではそのプラットフォームに投資したことを後悔しています。障害やサーバー過負荷の日があまりにも多いのです。とどめは、CodebergがAIを使っているプロジェクトを禁止すると決めたことでした。自分は「使いすぎ」という恣意的な閾値には達していないと思いますが、それでも他へ移るつもりです。
  • Super Mario Derivations
    • Nixを使った巧妙なトリックで、著者がSuper Mario 3のプレイ状態をエミュレータ内でNixの属性を使ってエンコードしていました。たとえばnix build '.#level1.rightb.rightb.rightab.rightb'は、レベル1を開始して、右+B(ダッシュしながら右へ)を2回、右+A+B(ダッシュ&ジャンプ)、そして再び右+B(ダッシュしながら右へ)を押すことを意味します。Nixがすべてのゲーム状態をキャッシュするので、ボタンの押し方を変えても前回から変わった部分だけを再計算すれば済みます。

まとめ

来月の目標

  • 『Refactoring English』について話すために5つのポッドキャストに売り込む。
  • Refactoring Englishのウェブサイトにユニーク読者3万人を集める。
  • 本の正式版1.0をリリースする。

手助けのお願い

  • 静的サイトのホスティングでおすすめがあれば教えてください。
  • もしClaire Giordanoをご存知なら、Talking Postgres(Postgresではなくテクニカルライティングについて話すゲストとして)に自分が良いゲストになると伝えてください。

この記事は「muse-spark-1.2-contributor」を使用して翻訳されました。

コメント