リーダーモードでnoteのリンクカードが消えるので、原因を調べて改善要望を送ってみた
RSS(Really Simple Syndication)という、Webサイトの更新情報を配信するための仕組みがあります。 RSSリーダーにブログなどを登録しておくと、複数のサイトの新着記事をまとめて確認でき、便利です。
noteの場合、クリエイターページのURLの末尾に「/rss」を付与するだけで取得できます。詳しい仕様はヘルプを参照してください。
iframe、RSSで、自分のサイトにnoteを表示する - noteヘルプセンター
AndroidでRSSを読むとき、私はRead Youというアプリを使っています。
ある日、Read Youで自分のnote記事を読んでいて、気になることがありました。
記事内に置いたリンクカードが表示されていません。
本文は読める。画像も表示される。
リンクカードだけが、きれいに消えています。
最初は「Read Youの問題かな」と思いました。
ところが、調べ始めたら思ったより話が広がりました。
そもそも、なぜ記事全文が読める?
まず気になったのが、
noteのRSSは全文配信ではないのに、なぜRead Youでは記事全文を読めるのか?
ということです。


通常のnoteが配信しているRSSには、記事本文の一部しか含まれていません。ちなみに法人向けの「note pro」では、RSSで全文配信することもできます。
ただし、note proは月額80,000円(税抜)。
個人で「RSSを全文配信したいな」という理由だけで契約するような料金ではありません。では、Read Youはどこから全文を持ってきているのでしょうか。

調べてみると、Read YouはWebページから本文を抽出するために、MozillaのReadabilityを利用していました。
Readabilityは、Webページの中から記事本文と思われる部分を抜き出し、読みやすい形に整理するためのライブラリです。
Firefoxのリーダービューにも使われています。そこでFirefoxで同じnote記事を開き、リーダービューを試してみました。
やはり、リンクカードは表示されません。
Vivaldiでもリンクカードが消えた
普段使っているVivaldiにもリーダービューがあります。
こちらでも同じ記事を試しました。
結果は同じ。
リンクカードは表示されません。
調べてみると、VivaldiのリーダービューもMozilla Readabilityを利用していました。ここまでは分かりやすいです。同じ仕組みを使っているなら、同じ部分が消えても不思議ではありません。
では、別の仕組みならどうなるのでしょうか。
Chromiumは別の仕組みだった
次にChromiumを調べてみました。
現在のChromiumには「リーディングモード」があります。こちらはReadabilityではなく、Read Anythingという別の仕組みです。
さらに調べていると、ChromiumにはDOM Distillerという別の本文抽出の仕組みもあることを知りました。
この時点では、
「Readabilityとは違う仕組みなら、リンクカードが残るかもしれない」
くらいに考えていました。
まずは現在のChromiumで使えるリーディングモードから試してみます。同じnote記事を開き、リーディングモードで表示してみました。
結果は、
やはりリンクカードが表示されません。
Readabilityとは別の実装でも消えました。
ここで「Readabilityだけの問題ではなさそうだな」と思い始めました。
Instapaperでも表示されない
「あとで読むサービス」として有名なInstapaperでも確認してみました。
Instapaperは独自の本文解析技術を使っています。
しかし、結果は同じでした。
リンクカードは表示されません。
ここまで確認したのは、
Read You
Firefox
Vivaldi
Chromium
Instapaper
です。
使われている本文抽出の仕組みは、すべて同じではありません。それなのに、noteのリンクカードは消えます。
noteのリンクカード自体が、本文抽出と相性の悪い構造なのでは?
そんな疑問が出てきました。
JavaScript実行後のHTMLを見てみる
最初に考えたのは、
リンクカードはJavaScriptで後から生成されるので、本文抽出側が取得できないのでは?
ということでした。
そこでChromiumの開発者ツールを使い、ページを表示した後のHTMLを保存して確認してみました。
リンクカードは存在しています。
つまり「JavaScriptが実行される前だから取得できなかった」という単純な話ではなさそうです。
実際のリンクカード周辺を見ると、おおむね次のような構造になっていました。
<div data-embed-service="note">
<iframe
class="note-embed"
src="/https://note.com/embed/notes/...">
</iframe>
<a
href="/https://note.com/..."
style="visibility: hidden;">
</a>
</div>なるほど。
見えているリンクカードの実体は iframe です。一方、親ページ側にもリンク先を示す a タグはあります。しかし、リンク先URLが設定されているものの、中身は空。さらに visibility: hidden で非表示になっています。
そういえば、以前から少し不思議に思っていたことがありました。
noteには、記事のフォントを明朝体に変更する設定があります。しかし、本文を明朝体にしてもリンクカード内の文字は明朝体になりません。今までは「リンクカードは別デザインだからかな」くらいに思っていました。
今回HTMLを確認して、少し納得しました。
リンクカードは本文の一部として直接描画されているのではなく、iframe の中に別のページとして表示されています。そのため、親ページである記事本文のフォント設定が、そのままリンクカード内まで引き継がれるわけではないようです。
以前から見ていた小さな違いが、今回確認したHTML構造とつながりました。
本文抽出側から見ると、
カード本体は iframe
親ページ側に見えるリンク文字列はない
a タグの中身は空
しかも非表示
という状態です。
iframe が本文抽出時に除外されたら、何も残りません。
複数のリーダーモードでリンクカードがきれいに消えた理由が、少し見えてきました。
せっかくなのでDOM Distiller系でも試してみた
Chromiumについて調べたときに見つけた、DOM Distiller。こちらも気になります。
ただ、今回試したChromiumでは、DOM Distillerを簡単に直接呼び出す方法が見つかりませんでした。さらに調べてみると、ChromiumのDOM DistillerをGoへ移植したGo-DomDistiller というものがあると分かりました。
今回はstable版を使って検証しました。
go get github.com/markusmobius/go-domdistiller@stableGoの開発環境をインストール。
小さな検証用プログラムを作り、先ほど保存したJavaScript実行後のHTMLを読み込ませます。
実際に使ったコードはこれです。
package main
import (
"fmt"
"os"
distiller "github.com/markusmobius/go-domdistiller"
)
func main() {
result, err := distiller.ApplyForFile("note-rendered.html", nil)
if err != nil {
panic(err)
}
err = os.WriteFile("distilled.html", []byte(result.HTML), 0644)
if err != nil {
panic(err)
}
fmt.Printf("distilled.html を作成しました(単語数: %d)\n", result.WordCount)
}最初は「RSSリーダーでリンクカードが表示されないな」というだけの話、だったんですけどね。
なぜかGoのプログラムを動かしています。
日曜日の午後が丸々つぶれました。
抽出後のHTMLを確認したところ、
リンクカードは消えていました。
さらに検索してみましたが、カードの代わりになる元記事へのURLも残っていません。完全に消えています。
もちろん、Go-DomDistillerはChromium本体のDOM Distillerそのものではありません。そのため、Chromium本体でも必ず同じ結果になるとは断定できません。
それでも、DOM Distiller系の実装でも同じ傾向になりました。
リンクカードの見た目を残してほしいわけではない
ここでひとつ整理しておきます。
私は、
リーダーモードでもnoteのリンクカードを同じデザインで表示してほしい
と言いたいわけではありません。
リーダーモードは、装飾などを取り除いて本文を読みやすくするための機能です。カードの画像や説明文が消えるのは理解できます。
気になるのは、
そこにリンクがあったことまで分からなくなる
ことです。
たとえば、
以前、WPS Officeをインストールする記事を書きました。
という文章の直後にリンクカードを置いたとします。
通常のnoteでは、その下に関連記事へのカードが表示されます。
しかし、リーダーモードでは、
以前、WPS Officeをインストールする記事を書きました。
で終わります。
「どの記事?」
となります。
リンクカードだけを使って関連記事への導線を作っていると、リンクが消えるだけでなく、文章のつながりまで少しおかしくなってしまいます。
noteへ改善要望を送ってみた
そこで、noteのお問い合わせから改善要望を送りました。
お願いしたのは、リンクカードをリーダーモードでも再現してほしい、ということではありません。
リンクカードが除外された場合でも、
関連記事:記事タイトル
あるいは、
のように、最低限リンクがあることだけでも分かるHTML構造にできないか、という要望です。
現在のHTMLを見る限り、リンク先URL自体は親ページ側にも存在しています。リンク先が分からないわけではなさそうです。
iframe の外側に、意味のある通常リンクを持たせることができれば、本文抽出後にも導線が残る可能性があります。
もちろん、私はnote内部の実装事情を知りません。
思っているほど単純な話ではないかもしれませんし、対応されるかどうかも分かりません。
とりあえず、今回確認した内容をまとめて改善要望として送ってみました。
文字列のリンクも置くことにする
note側が今後どう対応するかは分かりません。
では、今すぐ自分でできることは何か。
結論は単純です。
重要なリンクは、リンクカードだけに任せない。
たとえば、
以前、WPS Officeをインストールする記事を書きました。
関連記事:WPS OfficeをUbuntuにインストールしてみた
という形で、記事タイトルの文字列にもリンクを設定します。その下に、いつものリンクカードを置く。
通常のnoteではリンクカードが見た目の分かりやすい導線になります。
リーダーモードでリンクカードが消えても、通常の文字列リンクなら残ります。やや冗長な表記になりますが、これはRSSリーダーだけの話でもありません。
以前から使っているw3mのようなテキストブラウザでも、通常のリンクなら辿れます。考えてみれば、ずいぶん単純な対策でした。
まとめ
始まりは、Read Youで自分の記事を読んでいて、
「あれ? リンクカードがない」
と気付いたことでした。
Read Youだけの問題かと思ったら、
Firefoxでも消える。
Vivaldiでも消える。
別の仕組みを使うChromiumでも消える。
Instapaperでも消える。
最後にはGo-DomDistillerまで動かしていました。
調べた範囲では、JavaScript実行後のDOMにリンクカード自体は存在しています。
ただし、カード本体は iframe で、親ページ側の通常リンクは中身が空かつ非表示になっています。この構造が、本文抽出処理と相性が悪い原因のひとつではないかと考えています。
noteには改善要望を送りました。
リンクカードの仕様が変わるかどうかは分かりません。今は自分でできる対策をするだけです。
重要なリンクは、リンクカードだけに任せない。
リンクカードと一緒に、普通の文字列リンクも置く。
RSSリーダーでも、リーダーモードでも、テキストブラウザでも。リンクカードが消えても、リンクまで消えないようにしておこうと思います。
ちなみに、この記事に載せた外部サイトへのリンクも、リンクカードだけではなく文字列にリンクを設定しています。
今回調べたことを、さっそく実践してみました。
さて……
これから過去記事に置いたリンクカードを確認して、必要なところには文字列リンクを追加することにします。
......何記事あるんだろう。
あーあ、めんどくさい。
